Merge lp:~edwin-grubbs/launchpad/bug-482176-add-team-member-ajax-part3 into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Approved by: Aaron Bentley
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~edwin-grubbs/launchpad/bug-482176-add-team-member-ajax-part3
Merge into: lp:launchpad
Prerequisite: lp:~edwin-grubbs/launchpad/bug-482176-add-team-member-ajax-part2
Diff against target: 1635 lines (+279/-220)
57 files modified
lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt (+1/-1)
lib/lp/answers/doc/person.txt (+2/-2)
lib/lp/bugs/browser/tests/bug-views.txt (+1/-1)
lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt (+1/-1)
lib/lp/bugs/doc/bugnotification-sending.txt (+4/-2)
lib/lp/bugs/doc/bugtask.txt (+2/-1)
lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt (+1/-1)
lib/lp/code/stories/branches/xx-branch-deletion.txt (+1/-1)
lib/lp/code/stories/feeds/xx-revision-atom.txt (+1/-1)
lib/lp/registry/browser/team.py (+5/-3)
lib/lp/registry/browser/tests/peoplemerge-views.txt (+1/-1)
lib/lp/registry/browser/tests/person-views.txt (+1/-1)
lib/lp/registry/browser/tests/product-views.txt (+1/-1)
lib/lp/registry/browser/tests/projectgroupset-views.txt (+1/-1)
lib/lp/registry/browser/tests/team-views.txt (+4/-4)
lib/lp/registry/browser/tests/teammembership-views.txt (+1/-2)
lib/lp/registry/doc/announcement.txt (+1/-1)
lib/lp/registry/doc/commercialsubscription.txt (+1/-1)
lib/lp/registry/doc/mailinglist-email-notification.txt (+8/-5)
lib/lp/registry/doc/mailinglist-subscriptions.txt (+3/-3)
lib/lp/registry/doc/mailinglists.txt (+2/-1)
lib/lp/registry/doc/person-merge.txt (+3/-3)
lib/lp/registry/doc/person.txt (+2/-2)
lib/lp/registry/doc/private-team-visibility.txt (+3/-3)
lib/lp/registry/doc/teammembership-email-notification.txt (+7/-12)
lib/lp/registry/doc/teammembership.txt (+100/-63)
lib/lp/registry/doc/vocabularies.txt (+2/-3)
lib/lp/registry/stories/mailinglists/lifecycle.txt (+1/-1)
lib/lp/registry/stories/mailinglists/subscriptions.txt (+3/-3)
lib/lp/registry/stories/person/xx-admin-person-review.txt (+2/-1)
lib/lp/registry/stories/product/xx-product-edit.txt (+1/-1)
lib/lp/registry/stories/product/xx-productset.txt (+1/-1)
lib/lp/registry/stories/team/xx-team-add-my-teams.txt (+40/-38)
lib/lp/registry/stories/teammembership/20-managing-members.txt (+14/-5)
lib/lp/registry/stories/teammembership/private-team.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-add-member.txt (+15/-12)
lib/lp/registry/stories/teammembership/xx-expire-subscription.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-private-membership.txt (+4/-4)
lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt (+2/-1)
lib/lp/registry/stories/webservice/xx-private-membership.txt (+4/-3)
lib/lp/registry/stories/webservice/xx-source-package.txt (+1/-1)
lib/lp/registry/stories/webservice/xx-structuralsubscription.txt (+1/-1)
lib/lp/registry/tests/bug-249185.txt (+5/-4)
lib/lp/registry/tests/test_teammembership.py (+4/-4)
lib/lp/soyuz/browser/tests/archive-views.txt (+2/-2)
lib/lp/soyuz/browser/tests/build-views.txt (+1/-1)
lib/lp/soyuz/doc/archive.txt (+3/-2)
lib/lp/soyuz/doc/archivepermission.txt (+1/-1)
lib/lp/soyuz/doc/archivesubscriber.txt (+2/-1)
lib/lp/soyuz/doc/build-notification.txt (+1/-1)
lib/lp/soyuz/doc/build.txt (+3/-3)
lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt (+1/-1)
lib/lp/soyuz/doc/packageset.txt (+1/-1)
lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt (+1/-1)
lib/lp/soyuz/stories/soyuz/xx-private-builds.txt (+1/-1)
lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt (+1/-1)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-482176-add-team-member-ajax-part3
Reviewer Review Type Date Requested Status
Aaron Bentley (community) code Approve
Review via email: mp+16804@code.launchpad.net

Commit message

Add member via ajax link on team +index page.

To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :
Download full text (31.6 KiB)

Summary
-------

This branch fixes a bunch of tests. Most of the fixes are simple search and
replace, but there are a good 731 lines that are more complicated, so they
need a review instead of a rubber stamp. I have included those diff lines
in this comment so you don't have to read the automated diff.

Implementation details
----------------------

Display the correct informational message in the browser
corresponding to the new behavior for addMember().
    lib/lp/registry/browser/team.py

I changed the owners of several teams in this test so that
it tests the permissions more appropriately. Previously, it
was using foobar for everything, and that is a Launchpad admin,
so it effectively had admin access on all the teams.
    lib/lp/registry/doc/teammembership.txt

I changed the user for these tests, since salgado is also a
Launchpad admin.
    lib/lp/registry/stories/team/xx-team-add-my-teams.txt

Verify that the former members of a team are now only viewable
by the admins of the team on the +members page.
    lib/lp/registry/stories/teammembership/20-managing-members.txt

I changed some of the teams involved in the tests and the logged-in
user, since addMember() will fully add a team if the user is an
admin on both teams. If the user is only an admin on the team adding
another team, then addMember() will set the status to INVITED.
    lib/lp/registry/stories/teammembership/xx-add-member.txt
    lib/lp/registry/stories/teammembership/xx-private-membership.txt
    lib/lp/registry/stories/webservice/xx-private-membership.txt

In the REST API, the logged-in user is passed in as the reviewer
argument. Therefore, the no_priv user has to be used to create a
cyclical invitation as opposed to a cyclical active membership.
    lib/lp/registry/tests/test_teammembership.py

Tests
-----

./bin/test -vv -t registry

Pruned incremental diff
-----------------------
{{{
=== modified file 'lib/lp/registry/browser/team.py'
--- lib/lp/registry/browser/team.py 2009-12-10 18:11:38 +0000
+++ lib/lp/registry/browser/team.py 2010-01-04 17:12:48 +0000
@@ -993,9 +993,11 @@
         assert newmember != self.context, (
             "Can't add team to itself: %s" % newmember)

- self.context.addMember(newmember, reviewer=self.user,
- status=TeamMembershipStatus.APPROVED)
- if newmember.isTeam():
+ changed, new_status = self.context.addMember(
+ newmember, reviewer=self.user,
+ status=TeamMembershipStatus.APPROVED)
+
+ if new_status == TeamMembershipStatus.INVITED:
             msg = "%s has been invited to join this team." % (
                   newmember.unique_displayname)
         else:

=== modified file 'lib/lp/registry/doc/teammembership.txt'
--- lib/lp/registry/doc/teammembership.txt 2009-12-16 02:22:29 +0000
+++ lib/lp/registry/doc/teammembership.txt 2010-01-04 17:12:47 +0000
@@ -22,23 +22,28 @@
     >>> from zope.component import getUtility
     >>> from canonical.launchpad.interfaces import IPersonSet
     >>> personset = getUtility(IPersonSet)
- >>> foobar = personset.getByName('name16')
- >>> reviewer = foobar
+ >>> jblack = personset.getByName('jblack')
+ >>> nop...

Revision history for this message
Aaron Bentley (abentley) wrote :

The documentation is inverted here:

+First invite ubuntu-team to be member of the name20 team.

- >>> browser.open('http://launchpad.dev/~name21/+addmember')
- >>> browser.getControl('New member:').value = 'ubuntu-team'
+ >>> browser = setupBrowser(
+ ... auth='Basic <email address hidden>:test')
+ >>> browser.open('http://launchpad.dev/~ubuntu-team/+addmember')
+ >>> browser.getControl('New member:').value = 'name20'
     >>> browser.getControl('Add Member').click()

(name20 is added to ubuntu-team)

Other than that, this looks okay to land.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt'
2--- lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt 2009-09-16 08:11:22 +0000
3+++ lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt 2010-01-05 17:55:34 +0000
4@@ -239,7 +239,7 @@
5 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
6 >>> launchpad_beta_testers = getUtility(
7 ... ILaunchpadCelebrities).launchpad_beta_testers
8- >>> launchpad_beta_testers.addMember(foo_bar, reviewer=foo_bar)
9+ >>> ignored = launchpad_beta_testers.addMember(foo_bar, reviewer=foo_bar)
10 >>> foo_bar.inTeam(launchpad_beta_testers)
11 True
12
13
14=== modified file 'lib/lp/answers/doc/person.txt'
15--- lib/lp/answers/doc/person.txt 2009-04-17 10:32:16 +0000
16+++ lib/lp/answers/doc/person.txt 2010-01-05 17:55:34 +0000
17@@ -279,7 +279,7 @@
18 contact through his team membership.
19
20 >>> landscape_team = personset.getByName("landscape-developers")
21- >>> landscape_team.addMember(no_priv_raw, foo_bar_raw)
22+ >>> ignored = landscape_team.addMember(no_priv_raw, foo_bar_raw)
23 >>> no_priv_raw.inTeam(landscape_team)
24 True
25
26@@ -301,7 +301,7 @@
27 >>> translator_team = personset.getByName('ubuntu-translators')
28 >>> no_priv_raw.inTeam(translator_team)
29 False
30- >>> translator_team.addMember(landscape_team, carlos_raw)
31+ >>> ignored = translator_team.addMember(landscape_team, carlos_raw)
32
33 # We need to accept the invitation sent by the addMember() call in
34 # order to make landscape_team an actual member of translator_team.
35
36=== modified file 'lib/lp/bugs/browser/tests/bug-views.txt'
37--- lib/lp/bugs/browser/tests/bug-views.txt 2009-06-12 16:36:02 +0000
38+++ lib/lp/bugs/browser/tests/bug-views.txt 2010-01-05 17:55:34 +0000
39@@ -710,7 +710,7 @@
40 People in the team get to see the comments.
41
42 >>> login('foo.bar@canonical.com')
43- >>> syncing_team.addMember(no_priv, no_priv)
44+ >>> ignored = syncing_team.addMember(no_priv, no_priv)
45
46 >>> login('no-priv@canonical.com')
47 >>> view = BugTaskView(bug.bugtasks[0], LaunchpadTestRequest())
48
49=== modified file 'lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt'
50--- lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt 2009-06-12 16:36:02 +0000
51+++ lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt 2010-01-05 17:55:34 +0000
52@@ -64,7 +64,7 @@
53 Members of the syncing team will get the notifications.
54
55 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
56- >>> syncing_team.addMember(no_priv, no_priv)
57+ >>> ignored = syncing_team.addMember(no_priv, no_priv)
58 >>> transaction.commit()
59
60 >>> LaunchpadZopelessLayer.switchDbUser('bugnotification')
61
62=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
63--- lib/lp/bugs/doc/bugnotification-sending.txt 2009-12-05 18:37:28 +0000
64+++ lib/lp/bugs/doc/bugnotification-sending.txt 2010-01-05 17:55:34 +0000
65@@ -1280,7 +1280,8 @@
66 ... displayname='Concise Team Person',
67 ... email='conciseteam@example.com')
68 >>> concise_team_person.verbose_bugnotifications = True
69- >>> concise_team.addMember(concise_team_person, concise_team_person)
70+ >>> ignored = concise_team.addMember(
71+ ... concise_team_person, concise_team_person)
72 >>> bug.subscribe(concise_team, concise_team_person)
73 <BugSubscription...>
74
75@@ -1294,7 +1295,8 @@
76 ... displayname='Verbose Team Person',
77 ... email='verboseteam@example.com')
78 >>> verbose_team_person.verbose_bugnotifications = False
79- >>> verbose_team.addMember(verbose_team_person, verbose_team_person)
80+ >>> ignored = verbose_team.addMember(
81+ ... verbose_team_person, verbose_team_person)
82 >>> bug.subscribe(verbose_team, verbose_team_person)
83 <BugSubscription...>
84
85
86=== modified file 'lib/lp/bugs/doc/bugtask.txt'
87--- lib/lp/bugs/doc/bugtask.txt 2009-08-27 07:58:37 +0000
88+++ lib/lp/bugs/doc/bugtask.txt 2010-01-05 17:55:34 +0000
89@@ -959,7 +959,8 @@
90 Team *is* subscribed to the bug, No Privileges Person will see the private bug.
91
92 >>> login("mark@example.com")
93- >>> ubuntu_team.addMember(no_priv, reviewer=ubuntu_team.teamowner)
94+ >>> ignored = ubuntu_team.addMember(
95+ ... no_priv, reviewer=ubuntu_team.teamowner)
96
97 >>> login("no-priv@canonical.com")
98 >>> params = BugTaskSearchParams(
99
100=== modified file 'lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt'
101--- lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt 2009-09-02 12:33:41 +0000
102+++ lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt 2010-01-05 17:55:34 +0000
103@@ -55,7 +55,7 @@
104 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
105 >>> launchpad_beta_testers = getUtility(
106 ... ILaunchpadCelebrities).launchpad_beta_testers
107- >>> launchpad_beta_testers.addMember(mark, reviewer=foo_bar)
108+ >>> ignored = launchpad_beta_testers.addMember(mark, reviewer=foo_bar)
109 >>> mark.inTeam(launchpad_beta_testers)
110 True
111
112
113=== modified file 'lib/lp/code/stories/branches/xx-branch-deletion.txt'
114--- lib/lp/code/stories/branches/xx-branch-deletion.txt 2009-09-23 14:40:53 +0000
115+++ lib/lp/code/stories/branches/xx-branch-deletion.txt 2010-01-05 17:55:34 +0000
116@@ -84,7 +84,7 @@
117 >>> login(ANONYMOUS)
118 >>> name12 = getUtility(IPersonSet).getByName('name12')
119 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches
120- >>> removeSecurityProxy(ubuntu_branches).addMember(
121+ >>> ignored = removeSecurityProxy(ubuntu_branches).addMember(
122 ... name12, ubuntu_branches.teamowner)
123 >>> login_person(name12)
124 >>> branch = factory.makePackageBranch(owner=name12)
125
126=== modified file 'lib/lp/code/stories/feeds/xx-revision-atom.txt'
127--- lib/lp/code/stories/feeds/xx-revision-atom.txt 2009-07-09 05:12:34 +0000
128+++ lib/lp/code/stories/feeds/xx-revision-atom.txt 2010-01-05 17:55:34 +0000
129@@ -54,7 +54,7 @@
130
131 >>> login_person(mike)
132 >>> team = factory.makeTeam(mike, 'The M Team', name='m-team')
133- >>> team.addMember(mary, mike)
134+ >>> ignored = team.addMember(mary, mike)
135 >>> from lp.code.interfaces.revision import IRevisionSet
136 >>> from zope.component import getUtility
137 >>> revision_set = getUtility(IRevisionSet)
138
139=== modified file 'lib/lp/registry/browser/team.py'
140--- lib/lp/registry/browser/team.py 2009-12-10 18:11:38 +0000
141+++ lib/lp/registry/browser/team.py 2010-01-05 17:55:34 +0000
142@@ -993,9 +993,11 @@
143 assert newmember != self.context, (
144 "Can't add team to itself: %s" % newmember)
145
146- self.context.addMember(newmember, reviewer=self.user,
147- status=TeamMembershipStatus.APPROVED)
148- if newmember.isTeam():
149+ changed, new_status = self.context.addMember(
150+ newmember, reviewer=self.user,
151+ status=TeamMembershipStatus.APPROVED)
152+
153+ if new_status == TeamMembershipStatus.INVITED:
154 msg = "%s has been invited to join this team." % (
155 newmember.unique_displayname)
156 else:
157
158=== modified file 'lib/lp/registry/browser/tests/peoplemerge-views.txt'
159--- lib/lp/registry/browser/tests/peoplemerge-views.txt 2009-07-27 20:53:27 +0000
160+++ lib/lp/registry/browser/tests/peoplemerge-views.txt 2010-01-05 17:55:34 +0000
161@@ -38,7 +38,7 @@
162 >>> parent_team = factory.makeTeam()
163 >>> child_team = factory.makeTeam(name='child-team')
164 >>> random_team = factory.makeTeam()
165- >>> parent_team.addMember(
166+ >>> ignored = parent_team.addMember(
167 ... child_team, reviewer=parent_team.teamowner, force_team_add=True)
168 >>> form = {'field.dupe_person': child_team.name,
169 ... 'field.target_person': random_team.name,
170
171=== modified file 'lib/lp/registry/browser/tests/person-views.txt'
172--- lib/lp/registry/browser/tests/person-views.txt 2009-12-23 16:17:12 +0000
173+++ lib/lp/registry/browser/tests/person-views.txt 2010-01-05 17:55:34 +0000
174@@ -911,7 +911,7 @@
175
176 >>> login("admin@canonical.com")
177 >>> team = factory.makeTeam()
178- >>> team.addMember(sample_person, sample_person)
179+ >>> ignored = team.addMember(sample_person, sample_person)
180 >>> ppa = factory.makeArchive(distribution=ubuntu, owner=team)
181
182 >>> login(ANONYMOUS)
183
184=== modified file 'lib/lp/registry/browser/tests/product-views.txt'
185--- lib/lp/registry/browser/tests/product-views.txt 2009-11-23 14:52:25 +0000
186+++ lib/lp/registry/browser/tests/product-views.txt 2010-01-05 17:55:34 +0000
187@@ -142,7 +142,7 @@
188 >>> commercial_member = getUtility(IPersonSet).getByEmail(
189 ... 'commercial-member@canonical.com')
190 >>> registry_experts = getUtility(IPersonSet).getByName('registry')
191- >>> registry_experts.addMember(commercial_member, reviewer=mark)
192+ >>> ignored = registry_experts.addMember(commercial_member, reviewer=mark)
193 >>> login('commercial-member@canonical.com')
194 >>> view = create_initialized_view(firefox, name='+review-license')
195 >>> print view.label
196
197=== modified file 'lib/lp/registry/browser/tests/projectgroupset-views.txt'
198--- lib/lp/registry/browser/tests/projectgroupset-views.txt 2009-09-12 06:00:05 +0000
199+++ lib/lp/registry/browser/tests/projectgroupset-views.txt 2010-01-05 17:55:34 +0000
200@@ -44,7 +44,7 @@
201
202 >>> registry_member = factory.makePerson()
203 >>> login('foo.bar@canonical.com')
204- >>> registry.addMember(registry_member, registry.teamowner)
205+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
206 >>> registry_member.inTeam(registry)
207 True
208
209
210=== modified file 'lib/lp/registry/browser/tests/team-views.txt'
211--- lib/lp/registry/browser/tests/team-views.txt 2009-11-25 23:20:08 +0000
212+++ lib/lp/registry/browser/tests/team-views.txt 2010-01-05 17:55:34 +0000
213@@ -33,7 +33,7 @@
214 >>> salgado = person_set.getByName('salgado')
215 >>> mark = person_set.getByName('mark')
216 >>> login('foo.bar@canonical.com')
217- >>> ubuntu_team.addMember(salgado, reviewer=mark)
218+ >>> ignored = ubuntu_team.addMember(salgado, reviewer=mark)
219
220 >>> team_home = create_initialized_view(ubuntu_team, '+index')
221 >>> for member in team_home.recently_approved_members:
222@@ -125,7 +125,7 @@
223
224 >>> london_member = factory.makePerson(
225 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')
226- >>> context.addMember(london_member, mark)
227+ >>> ignored = context.addMember(london_member, mark)
228 >>> context.mapped_participants_count
229 1
230 >>> view = create_initialized_view(context, '+map')
231@@ -139,7 +139,7 @@
232
233 >>> brazil_member = factory.makePerson(
234 ... latitude=-23.60, longitude=-46.64, time_zone='America/Sao_Paulo')
235- >>> context.addMember(brazil_member, mark)
236+ >>> ignored = context.addMember(brazil_member, mark)
237 >>> context.mapped_participants_count
238 2
239 >>> view = create_initialized_view(context, '+map')
240@@ -153,7 +153,7 @@
241
242 >>> london_member2 = factory.makePerson(
243 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')
244- >>> context.addMember(london_member2, mark)
245+ >>> ignored = context.addMember(london_member2, mark)
246 >>> context.mapped_participants_count
247 3
248 >>> view = create_initialized_view(context, '+map')
249
250=== modified file 'lib/lp/registry/browser/tests/teammembership-views.txt'
251--- lib/lp/registry/browser/tests/teammembership-views.txt 2010-01-05 17:55:30 +0000
252+++ lib/lp/registry/browser/tests/teammembership-views.txt 2010-01-05 17:55:34 +0000
253@@ -62,8 +62,7 @@
254 >>> from lp.registry.browser.person import TeamInvitationView
255
256 >>> login_person(team_owner)
257- >>> super_team.addMember(team, team_owner)
258- True
259+ >>> ignored = super_team.addMember(team, team_owner)
260 >>> membership = membership_set.getByPersonAndTeam(team, super_team)
261 >>> login_person(team.teamowner)
262 >>> view = TeamInvitationView(membership, request)
263
264=== modified file 'lib/lp/registry/doc/announcement.txt'
265--- lib/lp/registry/doc/announcement.txt 2009-08-13 19:03:36 +0000
266+++ lib/lp/registry/doc/announcement.txt 2010-01-05 17:55:34 +0000
267@@ -32,7 +32,7 @@
268 >>> login('foo.bar@canonical.com')
269 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities
270 >>> beta = getUtility(ILaunchpadCelebrities).launchpad_beta_testers
271- >>> beta.addMember(mark, mark)
272+ >>> ignored = beta.addMember(mark, mark)
273 >>> from canonical.database.sqlbase import flush_database_updates
274 >>> flush_database_updates()
275 >>> logout()
276
277=== modified file 'lib/lp/registry/doc/commercialsubscription.txt'
278--- lib/lp/registry/doc/commercialsubscription.txt 2009-09-16 20:08:36 +0000
279+++ lib/lp/registry/doc/commercialsubscription.txt 2010-01-05 17:55:34 +0000
280@@ -550,7 +550,7 @@
281 >>> registry_member = factory.makePerson()
282 >>> celebs = getUtility(ILaunchpadCelebrities)
283 >>> registry = celebs.registry_experts
284- >>> registry.addMember(registry_member, registry.teamowner)
285+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
286 >>> logout()
287
288 >>> login_person(registry_member)
289
290=== modified file 'lib/lp/registry/doc/mailinglist-email-notification.txt'
291--- lib/lp/registry/doc/mailinglist-email-notification.txt 2009-05-12 08:11:06 +0000
292+++ lib/lp/registry/doc/mailinglist-email-notification.txt 2010-01-05 17:55:34 +0000
293@@ -10,7 +10,7 @@
294 >>> salgado = getUtility(IPersonSet).getByName('salgado')
295
296 >>> from lp.registry.tests.mailinglists_helper import (
297- ... new_team, new_list_for_team)
298+ ... new_team, new_list_for_team)
299
300 # login() as an admin so that we can call IPerson.join() on any
301 # person/team we want.
302@@ -33,7 +33,8 @@
303 >>> list_one.status.name
304 'ACTIVE'
305
306- >>> transaction.commit() # Send the emails.
307+ # Send the emails.
308+ >>> transaction.commit()
309
310 Both Anne and No Privileges Person receive the notifications, Anne as a
311 newly subscribed member and No Privileges Person as the owner of the
312@@ -89,7 +90,7 @@
313
314 >>> super_team = new_team('super-team', with_list=False)
315 >>> sub_team = new_team('sub-team', with_list=False)
316- >>> super_team.addMember(sub_team, salgado, force_team_add=True)
317+ >>> ignored = super_team.addMember(sub_team, salgado, force_team_add=True)
318 >>> anne.join(super_team)
319 >>> lars = factory.makePersonByName('Lars')
320 >>> lars.join(sub_team)
321@@ -120,7 +121,8 @@
322 >>> super_list.status.name
323 'ACTIVE'
324
325- >>> transaction.commit() # Send the emails.
326+ # Send the emails.
327+ >>> transaction.commit()
328 >>> len(stub.test_emails)
329 4
330 >>> print_emails(include_reply_to=True)
331@@ -220,6 +222,7 @@
332 >>> renewed_list.status.name
333 'ACTIVE'
334
335- >>> transaction.commit() # Send any outstanding emails.
336+ # Send any outstanding emails.
337+ >>> transaction.commit()
338 >>> len(stub.test_emails)
339 0
340
341=== modified file 'lib/lp/registry/doc/mailinglist-subscriptions.txt'
342--- lib/lp/registry/doc/mailinglist-subscriptions.txt 2009-05-06 15:13:39 +0000
343+++ lib/lp/registry/doc/mailinglist-subscriptions.txt 2010-01-05 17:55:34 +0000
344@@ -293,7 +293,7 @@
345 ... 'sub-team', team_owner)
346 >>> team_names.extend((super_team.name, sub_team.name))
347
348- >>> super_team.addMember(sub_team, salgado, force_team_add=True)
349+ >>> ignored = super_team.addMember(sub_team, salgado, force_team_add=True)
350 >>> lars = factory.makePersonByName('Lars')
351 >>> lars.join(super_team)
352 >>> lars.join(sub_team)
353@@ -333,7 +333,7 @@
354 ... 'team-three', team_owner)
355 >>> team_names.append(team_three.name)
356
357- >>> team_one.addMember(team_three, salgado, force_team_add=True)
358+ >>> ignored = team_one.addMember(team_three, salgado, force_team_add=True)
359 >>> dirk = factory.makePersonByName('Dirk')
360 >>> dirk.join(team_two)
361 >>> dirk.join(team_three)
362@@ -714,7 +714,7 @@
363 >>> team_five = factory.makeTeam(name='team-five', owner=team_owner)
364 >>> team_names.append(team_five.name)
365
366- >>> team_one.addMember(team_five, salgado, force_team_add=True)
367+ >>> ignored = team_one.addMember(team_five, salgado, force_team_add=True)
368 >>> gwen = factory.makePersonByName('Gwen')
369 >>> hank = factory.makePersonByName('Hank')
370 >>> iona = factory.makePersonByName('Iona')
371
372=== modified file 'lib/lp/registry/doc/mailinglists.txt'
373--- lib/lp/registry/doc/mailinglists.txt 2009-12-03 20:28:54 +0000
374+++ lib/lp/registry/doc/mailinglists.txt 2010-01-05 17:55:34 +0000
375@@ -82,7 +82,8 @@
376 >>> from canonical.launchpad.interfaces import TeamMembershipStatus
377 >>> login('foo.bar@canonical.com')
378 >>> bart = factory.makePersonByName('Bart')
379- >>> team_two.addMember(anne, bart, status=TeamMembershipStatus.ADMIN)
380+ >>> ignored = team_two.addMember(
381+ ... anne, bart, status=TeamMembershipStatus.ADMIN)
382 >>> login(ANONYMOUS)
383 >>> list_two = list_set.new(team_two, anne)
384 >>> list_two
385
386=== modified file 'lib/lp/registry/doc/person-merge.txt'
387--- lib/lp/registry/doc/person-merge.txt 2009-12-07 16:07:43 +0000
388+++ lib/lp/registry/doc/person-merge.txt 2010-01-05 17:55:34 +0000
389@@ -42,9 +42,9 @@
390 >>> ubuntu_team.teamowner = marilize
391
392 >>> ubuntu_translators = personset.getByName('ubuntu-translators')
393- >>> ubuntu_translators.addMember(marilize, marilize)
394+ >>> ignored = ubuntu_translators.addMember(marilize, marilize)
395 >>> rosetta_admins = personset.getByName('rosetta-admins')
396- >>> rosetta_admins.addMember(marilize, marilize)
397+ >>> ignored = rosetta_admins.addMember(marilize, marilize)
398
399 Karma gets reassigned to the person we merge into. Let's assign karma to
400 Marilize and save it for later comparison.
401@@ -348,7 +348,7 @@
402 >>> from canonical.launchpad.interfaces import IPollSubset, PollSecrecy
403 >>> test_team = personset.newTeam(sample, 'test-team', 'Test team')
404 >>> launchpad_devs = personset.getByName('launchpad')
405- >>> launchpad_devs.addMember(
406+ >>> ignored = launchpad_devs.addMember(
407 ... test_team, reviewer=launchpad_devs.teamowner, force_team_add=True)
408 >>> today = datetime.now(pytz.timezone('UTC'))
409 >>> tomorrow = today + timedelta(days=1)
410
411=== modified file 'lib/lp/registry/doc/person.txt'
412--- lib/lp/registry/doc/person.txt 2009-12-03 20:00:43 +0000
413+++ lib/lp/registry/doc/person.txt 2010-01-05 17:55:34 +0000
414@@ -482,7 +482,7 @@
415 And we can even add other members to our new team!
416
417 >>> login('foo.bar@canonical.com')
418- >>> not_a_person.addMember(lifeless, reviewer=ddaa)
419+ >>> ignored = not_a_person.addMember(lifeless, reviewer=ddaa)
420 >>> login(ANONYMOUS)
421 >>> [member.name for member in not_a_person.activemembers]
422 [u'ddaa', u'lifeless']
423@@ -1125,7 +1125,7 @@
424 >>> registry_member = factory.makePerson()
425 >>> celebs = getUtility(ILaunchpadCelebrities)
426 >>> registry = celebs.registry_experts
427- >>> registry.addMember(registry_member, registry.teamowner)
428+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
429 >>> logout()
430
431 >>> login_person(registry_member)
432
433=== modified file 'lib/lp/registry/doc/private-team-visibility.txt'
434--- lib/lp/registry/doc/private-team-visibility.txt 2010-01-04 23:17:19 +0000
435+++ lib/lp/registry/doc/private-team-visibility.txt 2010-01-05 17:55:34 +0000
436@@ -17,7 +17,7 @@
437 >>> priv_team = factory.makeTeam(owner=priv_owner, name="priv-team",
438 ... visibility=PersonVisibility.PRIVATE)
439 >>> login_person(priv_owner)
440- >>> priv_team.addMember(priv_member, reviewer=priv_owner)
441+ >>> ignored = priv_team.addMember(priv_member, reviewer=priv_owner)
442
443 The team owner can see the membership.
444
445@@ -57,7 +57,7 @@
446 >>> pub_member = factory.makePerson(name="pub-member")
447 >>> pub_team = factory.makeTeam(owner=pub_owner, name="pubteam")
448 >>> login_person(pub_owner)
449- >>> pub_team.addMember(pub_member, reviewer=pub_owner)
450+ >>> ignored = pub_team.addMember(pub_member, reviewer=pub_owner)
451
452 At this point the public team owner cannot see the priv-team's bits.
453
454@@ -67,7 +67,7 @@
455 Unauthorized: (<Person at ... priv-team (Priv Team)>, 'name', 'launchpad.View')
456
457 >>> login_person(priv_owner)
458- >>> priv_team.addMember(pub_team, reviewer=priv_owner)
459+ >>> ignored = priv_team.addMember(pub_team, reviewer=priv_owner)
460
461 The public team is not yet a member of the priv-team.
462
463
464=== modified file 'lib/lp/registry/doc/teammembership-email-notification.txt'
465--- lib/lp/registry/doc/teammembership-email-notification.txt 2010-01-05 17:55:30 +0000
466+++ lib/lp/registry/doc/teammembership-email-notification.txt 2010-01-05 17:55:34 +0000
467@@ -227,8 +227,7 @@
468
469 >>> cprov = personset.getByName('cprov')
470 >>> marilize = personset.getByName('marilize')
471- >>> ubuntu_team.addMember(marilize, reviewer=cprov)
472- True
473+ >>> ignored = ubuntu_team.addMember(marilize, reviewer=cprov)
474 >>> transaction.commit()
475 >>> len(stub.test_emails)
476 6
477@@ -277,8 +276,7 @@
478 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')
479 >>> mirror_admins.getTeamAdminsEmailAddresses()
480 ['mark@example.com']
481- >>> ubuntu_team.addMember(mirror_admins, reviewer=cprov)
482- True
483+ >>> ignored = ubuntu_team.addMember(mirror_admins, reviewer=cprov)
484 >>> transaction.commit()
485 >>> len(stub.test_emails)
486 1
487@@ -329,8 +327,7 @@
488 Similarly, a notification is sent if the invitation is declined.
489
490 >>> landscape = personset.getByName('landscape-developers')
491- >>> ubuntu_team.addMember(landscape, reviewer=cprov)
492- True
493+ >>> ignored = ubuntu_team.addMember(landscape, reviewer=cprov)
494
495 # Reset stub.test_emails as we don't care about the notification triggered
496 # by the addMember() call.
497@@ -363,8 +360,8 @@
498 passing force_team_add=True to the addMember() method.
499
500 >>> launchpad = personset.getByName('launchpad')
501- >>> ubuntu_team.addMember(launchpad, reviewer=cprov, force_team_add=True)
502- True
503+ >>> ignored = ubuntu_team.addMember(
504+ ... launchpad, reviewer=cprov, force_team_add=True)
505 >>> flush_database_updates()
506 >>> transaction.commit()
507 >>> len(stub.test_emails)
508@@ -854,8 +851,7 @@
509 >>> dummy = pop_notifications()
510 >>> member = factory.makePerson(
511 ... name='team-member', email='team-member@example.com')
512- >>> team_one.addMember(member, owner)
513- True
514+ >>> ignored = team_one.addMember(member, owner)
515 >>> print_distinct_emails()
516 From: Team One ...
517 ----------------------------------------
518@@ -881,8 +877,7 @@
519
520 >>> team_two = factory.makeTeam(
521 ... name='team-two', email='team-two@example.com', owner=owner)
522- >>> team_one.addMember(team_two, owner, force_team_add=True)
523- True
524+ >>> ignored = team_one.addMember(team_two, owner, force_team_add=True)
525 >>> print_distinct_emails()
526 From: Team One ...
527 ----------------------------------------
528
529=== modified file 'lib/lp/registry/doc/teammembership.txt'
530--- lib/lp/registry/doc/teammembership.txt 2010-01-05 17:55:30 +0000
531+++ lib/lp/registry/doc/teammembership.txt 2010-01-05 17:55:34 +0000
532@@ -22,23 +22,28 @@
533 >>> from zope.component import getUtility
534 >>> from canonical.launchpad.interfaces import IPersonSet
535 >>> personset = getUtility(IPersonSet)
536- >>> foobar = personset.getByName('name16')
537- >>> reviewer = foobar
538+ >>> jblack = personset.getByName('jblack')
539+ >>> nopriv = personset.getByName('no-priv')
540+ >>> jdub = personset.getByName('jdub')
541+ >>> reviewer = nopriv
542 >>> t1 = personset.newTeam(
543- ... foobar, 't1', 't1',
544+ ... jblack, 't1', 't1',
545 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
546 >>> t2 = personset.newTeam(
547- ... foobar, 't2', 't2',
548+ ... nopriv, 't2', 't2',
549 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
550 >>> t3 = personset.newTeam(
551- ... foobar, 't3', 't3',
552+ ... jdub, 't3', 't3',
553 ... subscriptionpolicy=TeamSubscriptionPolicy.MODERATED)
554 >>> t4 = personset.newTeam(
555- ... foobar, 't4', 't4',
556+ ... nopriv, 't4', 't4',
557 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
558 >>> t5 = personset.newTeam(
559- ... foobar, 't5', 't5',
560+ ... nopriv, 't5', 't5',
561 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
562+ >>> t6 = personset.newTeam(
563+ ... jdub, 't6', 't6',
564+ ... subscriptionpolicy=TeamSubscriptionPolicy.MODERATED)
565
566 # Make sure the teams have predictable (and different) creation dates as
567 # some of our tests depend on that.
568@@ -66,15 +71,15 @@
569 member of that team --somebody has to approve his membership first:
570
571 >>> [m.displayname for m in t4.allmembers]
572- [u'Foo Bar', u'Guilherme Salgado']
573+ [u'Guilherme Salgado', u'No Privileges Person']
574
575 >>> [m.displayname for m in t3.allmembers]
576- [u'Foo Bar']
577+ [u'Jeff Waugh']
578 >>> login_person(t3.teamowner)
579 >>> t3.setMembershipData(salgado, TeamMembershipStatus.APPROVED, reviewer)
580 >>> flush_database_updates()
581 >>> [m.displayname for m in t3.allmembers]
582- [u'Foo Bar', u'Guilherme Salgado']
583+ [u'Guilherme Salgado', u'Jeff Waugh']
584
585 The join() method is not allowed for teams whose subscription policy is
586 RESTRICTED. And it'll be a no-op in case the user has already joined the
587@@ -141,12 +146,12 @@
588 # Log in as the team owner.
589 >>> login_person(t3.teamowner)
590
591-addMember returns True if the member got added (i.e. he wasn't already a
592-member of the team).
593+If the member was added (i.e. he wasn't already a member of the team),
594+addMember returns a tuple with True plus the new membership status.
595
596 >>> t3.addMember(
597 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)
598- True
599+ (True, <DBItem TeamMembershipStatus.ADMIN...)
600 >>> from canonical.launchpad.interfaces import ITeamMembershipSet
601 >>> membershipset = getUtility(ITeamMembershipSet)
602 >>> flush_database_updates()
603@@ -158,26 +163,26 @@
604 >>> salgado in t3.activemembers
605 True
606
607-addMember returns True also when the member is added as a proposed
608-member.
609+addMember returns (True, PROPOSED) also when the member is added as a
610+proposed member.
611
612 >>> marilize = personset.getByName('marilize')
613 >>> t3.addMember(
614 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)
615- True
616+ (True, <DBItem TeamMembershipStatus.PROPOSED...)
617 >>> flush_database_updates()
618 >>> marilize in t3.activemembers
619 False
620
621 If addMember is called with a person that is already a member, it
622-returns False.
623+returns a tuple with False and the current status of the membership.
624
625 >>> t3.addMember(
626 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)
627- False
628+ (False, <DBItem TeamMembershipStatus.ADMIN...)
629 >>> t3.addMember(
630 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)
631- False
632+ (False, <DBItem TeamMembershipStatus.PROPOSED...)
633
634 As expected, the membership object implements ITeamMembership.
635
636@@ -188,29 +193,37 @@
637
638 Note that, by default, the ITeam.addMember() API works slightly different
639 when the added member is a team. In that case the team will actually be
640-invited to be a member and one of the team's admins will have to accpet the
641+invited to be a member and one of the team's admins will have to accept the
642 invitation before the team is made a member.
643
644- >>> t1.addMember(t2, reviewer)
645+ >>> login_person(t1.teamowner)
646+
647+ # If the reviewer were also an admin of the team being added,
648+ # the status would go to APPROVED instead of INVITED.
649+ >>> t2.teamowner != t1.teamowner
650 True
651+ >>> t1.addMember(t2, reviewer=t1.teamowner)
652+ (True, <DBItem TeamMembershipStatus.INVITED...)
653 >>> membership = membershipset.getByPersonAndTeam(t2, t1)
654 >>> membership.status == TeamMembershipStatus.INVITED
655 True
656 >>> [m.displayname for m in t1.allmembers]
657- [u'Foo Bar']
658+ [u'James Blackwell']
659
660 Once one of the t2 admins approve the membership, t2 is shown as a member
661-of t1.
662+of t1 and the owner of t2 is an indirect member.
663
664 >>> login_person(t2.teamowner)
665 >>> t2.acceptInvitationToBeMemberOf(t1, comment='something')
666+ >>> [m.displayname for m in t1.activemembers]
667+ [u'James Blackwell', u't2']
668 >>> [m.displayname for m in t1.allmembers]
669- [u'Foo Bar', u't2']
670+ [u'James Blackwell', u'No Privileges Person', u't2']
671
672 A team admin can also decline an invitation made to his team.
673
674 >>> t2.addMember(t3, reviewer=mark)
675- True
676+ (True, <DBItem TeamMembershipStatus.INVITED...)
677 >>> login_person(t3.teamowner)
678 >>> t3.declineInvitationToBeMemberOf(t2, comment='something')
679 >>> membership = membershipset.getByPersonAndTeam(t3, t2)
680@@ -222,21 +235,40 @@
681 force_team_add=True to addMember(). We'll use that to add t3 as a member of
682 t2, thus making all t3 members be considered members of t2 as well.
683
684- >>> login_person(t3.teamowner)
685- >>> t2.addMember(t3, reviewer=mark, force_team_add=True)
686+ >>> login_person(t2.teamowner)
687+
688+ # If the reviewer is also an admin of the team being added,
689+ # force_team_add is unnecessary, and we can't prove that that
690+ # argument works.
691+ >>> t3.teamowner != t2.teamowner
692 True
693+ >>> t2.addMember(t3, reviewer=t2.teamowner, force_team_add=True)
694+ (True, <DBItem TeamMembershipStatus.APPROVED...)
695 >>> [m.displayname for m in t2.allmembers]
696- [u'Foo Bar', u'Guilherme Salgado', u't3']
697+ [u'Guilherme Salgado', u'Jeff Waugh', u'No Privileges Person', u't3']
698
699 And members of t1 as well, since t2 is a member of t1.
700
701 >>> [m.displayname for m in t1.allmembers]
702- [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']
703+ [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
704+ u'No Privileges Person', u't2', u't3']
705+
706+
707+Passing in force_team_add=True is not necessary if the reviewer is the
708+admin of the team being added.
709+
710+ >>> login_person(t3.teamowner)
711+ >>> t6.addMember(t3, reviewer=t3.teamowner)
712+ (True, <DBItem TeamMembershipStatus.APPROVED...)
713+ >>> [m.displayname for m in t6.allmembers]
714+ [u'Guilherme Salgado', u'Jeff Waugh', u't3']
715
716 Can we add t2 as a member of t3? No, we prevent this kind of loop, and users
717 can't do this because our vocabularies won't allow members that would cause
718 loops.
719
720+ >>> foobar = personset.getByEmail('foo.bar@canonical.com')
721+ >>> login_person(foobar)
722 >>> t3.addMember(t2, reviewer)
723 Traceback (most recent call last):
724 ...
725@@ -246,19 +278,21 @@
726 Adding t2 as a member of t5 will add all t2 members as t5 members too.
727
728 >>> t5.addMember(t2, reviewer, force_team_add=True)
729- True
730+ (True, <DBItem TeamMembershipStatus.APPROVED...)
731 >>> [m.displayname for m in t5.allmembers]
732- [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']
733+ [u'Guilherme Salgado', u'Jeff Waugh', u'No Privileges Person',
734+ u't2', u't3']
735
736 Adding t5 and t1 as members of t4 will add all t5 and t1 members as t4
737 members too.
738
739 >>> t4.addMember(t5, reviewer, force_team_add=True)
740- True
741+ (True, <DBItem TeamMembershipStatus.APPROVED...)
742 >>> t4.addMember(t1, reviewer, force_team_add=True)
743- True
744+ (True, <DBItem TeamMembershipStatus.APPROVED...)
745 >>> [m.displayname for m in t4.allmembers]
746- [u'Foo Bar', u'Guilherme Salgado', u't1', u't2', u't3', u't5']
747+ [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
748+ u'No Privileges Person', u't1', u't2', u't3', u't5']
749
750 >>> flush_database_updates()
751
752@@ -305,18 +339,20 @@
753 member anymore, it doesn't have any members apart from its owner.
754
755 >>> [m.displayname for m in t5.allmembers]
756- [u'Foo Bar']
757+ [u'No Privileges Person']
758
759 Removing t2 from t5 won't remove it from t4, because t2 is also a member of
760 t1, which is a member of t4.
761
762 >>> [m.displayname for m in t4.allmembers]
763- [u'Foo Bar', u'Guilherme Salgado', u't1', u't2', u't3', u't5']
764+ [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
765+ u'No Privileges Person', u't1', u't2', u't3', u't5']
766
767 Nothing changes in t1, because t5 wasn't one of its members.
768
769 >>> [m.displayname for m in t1.allmembers]
770- [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']
771+ [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
772+ u'No Privileges Person', u't2', u't3']
773
774 If 'Guilherme Salgado' decides to leave t3, he'll also be removed from t1
775 and t2, but not from t4, because he's a direct member of t4.
776@@ -350,31 +386,31 @@
777
778 >>> cprov = getUtility(IPersonSet).getByName('cprov')
779 >>> t3.addMember(cprov, reviewer)
780- True
781+ (True, <DBItem TeamMembershipStatus.APPROVED...)
782 >>> [m.displayname for m in t3.allmembers]
783- [u'Celso Providelo', u'Foo Bar']
784+ [...u'Celso Providelo'...
785
786 >>> [m.displayname for m in t2.allmembers]
787- [u'Celso Providelo', u'Foo Bar', u't3']
788+ [...u'Celso Providelo'...
789
790 >>> [m.displayname for m in t1.allmembers]
791- [u'Celso Providelo', u'Foo Bar', u't2', u't3']
792+ [...u'Celso Providelo'...
793
794 >>> [m.displayname for m in t4.allmembers]
795- [u'Celso Providelo', u'Foo Bar', u'Guilherme Salgado', u't1', u't2',
796- u't3', u't5']
797-
798-
799-It's important to note that even if Foo Bar leaves the team he's the owner,
800-he'll retains his rights over the team because he's the team's owner. This
801-ensures we'll never have teams which can't be managed.
802-
803- >>> login_person(foobar)
804- >>> foobar.leave(t5)
805+ [...u'Celso Providelo'...
806+
807+
808+It's important to note that even if the owner leaves the team, which
809+removes his membership, he will still be the team's owner and retain his
810+rights over it. This ensures we'll never have teams which can't be
811+managed.
812+
813+ >>> login_person(t5.teamowner)
814+ >>> t5.teamowner.leave(t5)
815 >>> flush_database_updates()
816 >>> [m.displayname for m in t5.allmembers]
817 []
818- >>> foobar.inTeam(t5)
819+ >>> t5.teamowner.inTeam(t5)
820 True
821
822
823@@ -390,7 +426,7 @@
824
825 # Foo Bar is a launchpad admin, but even so he can't change a membership's
826 # status/expiry-date by hand.
827- >>> login('foo.bar@canonical.com')
828+ >>> login_person(foobar)
829 >>> membership = foobar.myactivememberships[0]
830 >>> membership.status = None
831 Traceback (most recent call last):
832@@ -709,7 +745,7 @@
833
834 >>> [(membership.person.name, membership.status.title)
835 ... for membership in t3.member_memberships]
836- [(u'cprov', 'Approved'), (u'name16', 'Administrator')]
837+ [(u'cprov', 'Approved'), (u'jdub', 'Administrator')]
838
839 A team has a number of other methods that return the people which are members
840 of it, all based on Person.getMembersByStatus:
841@@ -748,7 +784,7 @@
842 admin members plus the owner in case he is not one of the admin members.
843
844 >>> [admin.unique_displayname for admin in t3.adminmembers]
845- [u'Foo Bar (name16)']
846+ [u'Jeff Waugh (jdub)']
847 >>> list(t3.getDirectAdministrators()) == list(t3.adminmembers)
848 True
849
850@@ -823,7 +859,7 @@
851 >>> admins = getUtility(IPersonSet).getByName('admins')
852 >>> login_person(t1.teamowner)
853 >>> t1.addMember(admins, reviewer=t1.teamowner, force_team_add=True)
854- True
855+ (True, <DBItem TeamMembershipStatus.APPROVED...)
856 >>> flush_database_updates()
857 >>> print '\n'.join(sorted(
858 ... team.name for team in salgado.teams_participated_in))
859@@ -834,11 +870,12 @@
860 t1
861 t4
862
863-On the other hand, making t2 a member of admins won't change anything
864+On the other hand, making t3 a member of admins won't change anything
865 for Salgado.
866
867- >>> admins.addMember(t2, reviewer=admins.teamowner, force_team_add=True)
868- True
869+ >>> login_person(foobar)
870+ >>> admins.addMember(t3, reviewer=admins.teamowner, force_team_add=True)
871+ (True, <DBItem TeamMembershipStatus.APPROVED...)
872 >>> flush_database_updates()
873 >>> print '\n'.join(sorted(
874 ... team.name for team in salgado.teams_participated_in))
875@@ -855,8 +892,8 @@
876 Person instances have membership caches (_inTeam_cache) to avoid the
877 need to reissue identical membership queries repeatedly. (This test uses
878 Person directly to allow us access to an unproxied object, since
879-_inTeam_cache is private, and TeamMembershipSet directly to allow us to
880-call TeamMembership.setStatus, which is private).
881+_inTeam_cache is private, and it uses TeamMembershipSet directly to allow
882+us to call TeamMembership.setStatus, which is private).
883
884 >>> from lp.registry.model.person import Person
885 >>> from lp.registry.model.teammembership import TeamMembershipSet
886@@ -864,7 +901,7 @@
887 >>> no_priv.inTeam(admins)
888 False
889 >>> no_priv._inTeam_cache
890- {25: False}
891+ {...25: False...}
892
893 This cache is cleared when memberships are created:
894
895@@ -920,7 +957,7 @@
896 >>> transaction.commit()
897
898 >>> [m.displayname for m in t3.allmembers]
899- [u'Bad-user', u'Foo Bar']
900+ [u'Bad-user', u'Jeff Waugh']
901 >>> bad_user.is_valid_person
902 False
903 >>> print bad_user.preferredemail
904
905=== modified file 'lib/lp/registry/doc/vocabularies.txt'
906--- lib/lp/registry/doc/vocabularies.txt 2009-12-07 16:07:43 +0000
907+++ lib/lp/registry/doc/vocabularies.txt 2010-01-05 17:55:34 +0000
908@@ -255,8 +255,7 @@
909
910 >>> from canonical.launchpad.interfaces import PersonVisibility
911 >>> otherteam = person_set.getByName('otherteam')
912- >>> otherteam.addMember(foo_bar, foo_bar)
913-
914+ >>> ignored = otherteam.addMember(foo_bar, foo_bar)
915 >>> otherteam.visibility = PersonVisibility.PRIVATE_MEMBERSHIP
916 >>> for term in person_active_membership:
917 ... print term.token, term.value.displayname, term.title
918@@ -1398,7 +1397,7 @@
919 >>> registry_member = factory.makePerson()
920 >>> celebs = getUtility(ILaunchpadCelebrities)
921 >>> registry = celebs.registry_experts
922- >>> registry.addMember(registry_member, registry.teamowner)
923+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
924 >>> logout()
925
926 >>> login_person(registry_member)
927
928=== modified file 'lib/lp/registry/stories/mailinglists/lifecycle.txt'
929--- lib/lp/registry/stories/mailinglists/lifecycle.txt 2009-12-03 21:19:49 +0000
930+++ lib/lp/registry/stories/mailinglists/lifecycle.txt 2010-01-05 17:55:34 +0000
931@@ -363,7 +363,7 @@
932 >>> person_set = getUtility(IPersonSet)
933 >>> test = person_set.getByName('name12')
934 >>> experts = getUtility(ILaunchpadCelebrities).mailing_list_experts
935- >>> experts.addMember(test, reviewer=experts.teamowner)
936+ >>> ignored = experts.addMember(test, reviewer=experts.teamowner)
937 >>> logout()
938 >>> transaction.commit()
939
940
941=== modified file 'lib/lp/registry/stories/mailinglists/subscriptions.txt'
942--- lib/lp/registry/stories/mailinglists/subscriptions.txt 2009-12-03 20:28:54 +0000
943+++ lib/lp/registry/stories/mailinglists/subscriptions.txt 2010-01-05 17:55:34 +0000
944@@ -195,7 +195,7 @@
945 >>> person_set = getUtility(IPersonSet)
946 >>> jdub = person_set.getByName('jdub')
947 >>> mark = person_set.getByName('mark')
948- >>> beta.addMember(jdub, reviewer=mark)
949+ >>> ignored = beta.addMember(jdub, reviewer=mark)
950 >>> from canonical.database.sqlbase import flush_database_updates
951 >>> flush_database_updates()
952 >>> logout()
953@@ -424,9 +424,9 @@
954 >>> salgado = person_set.getByName('salgado')
955 >>> jordi = person_set.getByName('jordi')
956 >>> rosetta_admins = person_set.getByName('rosetta-admins')
957- >>> rosetta_admins.addMember(salgado, reviewer=mark)
958+ >>> ignored = rosetta_admins.addMember(salgado, reviewer=mark)
959 >>> rosetta_admins.mailing_list.subscribe(salgado)
960- >>> rosetta_admins.addMember(jordi, reviewer=mark)
961+ >>> ignored = rosetta_admins.addMember(jordi, reviewer=mark)
962 >>> rosetta_admins.mailing_list.subscribe(jordi)
963 >>> logout()
964 >>> browser.reload()
965
966=== modified file 'lib/lp/registry/stories/person/xx-admin-person-review.txt'
967--- lib/lp/registry/stories/person/xx-admin-person-review.txt 2010-01-04 10:24:29 +0000
968+++ lib/lp/registry/stories/person/xx-admin-person-review.txt 2010-01-05 17:55:34 +0000
969@@ -103,7 +103,8 @@
970 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities
971 >>> from zope.component import getUtility
972 >>> registry_team = getUtility(ILaunchpadCelebrities).registry_experts
973- >>> registry_team.addMember(registry_expert, registry_team.teamowner)
974+ >>> ignored = registry_team.addMember(
975+ ... registry_expert, registry_team.teamowner)
976 >>> print registry_expert.inTeam(registry_team)
977 True
978 >>> logout()
979
980=== modified file 'lib/lp/registry/stories/product/xx-product-edit.txt'
981--- lib/lp/registry/stories/product/xx-product-edit.txt 2009-10-08 16:29:45 +0000
982+++ lib/lp/registry/stories/product/xx-product-edit.txt 2010-01-05 17:55:34 +0000
983@@ -292,7 +292,7 @@
984 ... name='reggie', email='reggie@example.com', password='test')
985 >>> celebs = getUtility(ILaunchpadCelebrities)
986 >>> registry = celebs.registry_experts
987- >>> registry.addMember(registry_member, registry.teamowner)
988+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
989 >>> logout()
990
991 >>> registry_browser = setupBrowser(
992
993=== modified file 'lib/lp/registry/stories/product/xx-productset.txt'
994--- lib/lp/registry/stories/product/xx-productset.txt 2009-09-18 17:38:50 +0000
995+++ lib/lp/registry/stories/product/xx-productset.txt 2010-01-05 17:55:34 +0000
996@@ -23,7 +23,7 @@
997 ... name='reggie', email='reggie@example.com', password='test')
998 >>> celebs = getUtility(ILaunchpadCelebrities)
999 >>> registry = celebs.registry_experts
1000- >>> registry.addMember(registry_member, registry.teamowner)
1001+ >>> ignored = registry.addMember(registry_member, registry.teamowner)
1002 >>> logout()
1003
1004 >>> registry_browser = setupBrowser(
1005
1006=== modified file 'lib/lp/registry/stories/team/xx-team-add-my-teams.txt'
1007--- lib/lp/registry/stories/team/xx-team-add-my-teams.txt 2009-11-22 15:43:16 +0000
1008+++ lib/lp/registry/stories/team/xx-team-add-my-teams.txt 2010-01-05 17:55:34 +0000
1009@@ -6,8 +6,9 @@
1010 This is done from the +add-my-teams page, which is linked from a team's
1011 home page.
1012
1013- >>> browser = setupBrowser(auth='Basic salgado@ubuntu.com:zeca')
1014- >>> browser.open('http://launchpad.dev/~ubuntu-team')
1015+ >>> browser = setupBrowser(
1016+ ... auth='Basic colin.watson@ubuntulinux.com:test')
1017+ >>> browser.open('http://launchpad.dev/~name21')
1018 >>> browser.getLink('Add one of my teams').click()
1019 >>> browser.title
1020 'Propose/add one of your teams to another one...
1021@@ -18,47 +19,48 @@
1022 >>> print extract_text(find_tag_by_id(browser.contents, 'candidates'))
1023 This is a moderated team, so one of its administrators will have
1024 to review any memberships you propose.
1025- Launchpad Administrators
1026- Mailing List Experts
1027- Rosetta Administrators
1028+ GuadaMen
1029+ Ubuntu Security Team
1030+ Ubuntu Team
1031 or Cancel
1032
1033-We'll now propose Launchpad Administrators as a member of Ubuntu Team.
1034+We'll now propose Ubuntu Team as a member of the Hoary Gnome Team (name21).
1035
1036- >>> browser.getControl(name='field.teams').value = ['admins']
1037+ >>> browser.open('http://launchpad.dev/~name21')
1038+ >>> link = browser.getLink('Add one of my teams')
1039+ >>> link.click()
1040+ >>> browser.getControl(name='field.teams').value = ['ubuntu-team']
1041 >>> browser.getControl('Continue').click()
1042 >>> browser.title
1043- 'Ubuntu Team in Launchpad'
1044+ 'Hoary Gnome Team in Launchpad'
1045 >>> print get_feedback_messages(browser.contents)
1046- [u'Launchpad Administrators has been proposed to this team.']
1047+ [u'Ubuntu Team has been proposed to this team.']
1048 >>> print extract_text(
1049- ... find_tag_by_id(browser.contents, 'recently-applied'))
1050+ ... find_tag_by_id(browser.contents, 'recently-proposed'))
1051 Pending approval
1052- Launchpad Administrators
1053- ...
1054+ Ubuntu Team...
1055
1056 If it were an OPEN team, we'd be able to directly add any of our teams as
1057 members.
1058
1059- >>> admin_browser.open('http://launchpad.dev/~ubuntu-team/+edit')
1060+ >>> admin_browser.open('http://launchpad.dev/~name21/+edit')
1061 >>> admin_browser.getControl(
1062 ... name='field.subscriptionpolicy').displayValue = ['Open Team']
1063 >>> admin_browser.getControl('Save').click()
1064 >>> admin_browser.title
1065- 'Ubuntu Team in Launchpad'
1066+ 'Hoary Gnome Team in Launchpad'
1067
1068- >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')
1069- >>> browser.getControl(name='field.teams').value = ['rosetta-admins']
1070+ >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
1071+ >>> browser.getControl(name='field.teams').value = ['ubuntu-team']
1072 >>> browser.getControl('Continue').click()
1073 >>> browser.title
1074- 'Ubuntu Team in Launchpad'
1075+ 'Hoary Gnome Team in Launchpad'
1076 >>> print get_feedback_messages(browser.contents)
1077- [u'Rosetta Administrators has been added to this team.']
1078+ [u'Ubuntu Team has been added to this team.']
1079 >>> print extract_text(
1080 ... find_tag_by_id(browser.contents, 'recently-approved'))
1081- Recently approved
1082- Rosetta Administrators
1083- ...
1084+ Latest members
1085+ Ubuntu Team...
1086
1087 In the case of restricted teams, though, there is no way to propose any of
1088 your teams as members.
1089@@ -88,38 +90,38 @@
1090 Traceback (most recent call last):
1091 Unauthorized:...
1092
1093-You also can't propose a team to itself. Here although Salgado is usually
1094-allowed to propose Launchpad Administrators in other team, it doesn't
1095-appear in the list when proposing a team for the Launchpad
1096-Administrators team. Likewise Mailing List Experts isn't shown because
1097-the Launchpad Administrators are a member of Mailing List Experts.
1098-Adding Mailing List Experts would create a cycle.
1099+You also can't propose a team to itself. Here although Colin Watson is
1100+usually allowed to propose Guadamen in other team, it doesn't appear in
1101+the list when proposing a team for the Guadamen team. Likewise Mailing
1102+List Experts isn't shown because the Launchpad Administrators are a
1103+member of Mailing List Experts. Adding Mailing List Experts would
1104+create a cycle.
1105
1106- >>> browser.open('http://launchpad.dev/~admins/+add-my-teams')
1107+ >>> browser.open('http://launchpad.dev/~guadamen/+add-my-teams')
1108 >>> browser.getControl(name='field.teams').options
1109- ['rosetta-admins']
1110+ ['ubuntu-security']
1111
1112 Teams that are already member of the team can't be proposed or added.
1113-For example, Rosetta Administrators is not in the list of choices
1114-anymore of the Ubuntu Team:
1115+For example, Ubuntu Team is not in the list of choices
1116+anymore of the Hoary Gnome Team:
1117
1118- >>> admin_browser.open('http://launchpad.dev/~ubuntu-team/+edit')
1119+ >>> admin_browser.open('http://launchpad.dev/~name21/+edit')
1120 >>> admin_browser.getControl(
1121 ... name='field.subscriptionpolicy').displayValue = ['Open']
1122 >>> admin_browser.getControl('Save').click()
1123
1124- >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')
1125+ >>> browser.open('http://launchpad.dev/~name21/+members')
1126+ >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
1127 >>> browser.getControl(name='field.teams').options
1128- ['admins', 'mailing-list-experts']
1129+ ['guadamen', 'ubuntu-security']
1130 >>> browser.getControl(name='field.teams').value = [
1131- ... 'admins', 'mailing-list-experts']
1132+ ... 'guadamen', 'ubuntu-security']
1133 >>> browser.getControl('Continue').click()
1134 >>> print "\n".join(get_feedback_messages(browser.contents))
1135- Launchpad Administrators, Mailing List Experts have been added to this
1136- team.
1137+ GuadaMen, Ubuntu Security Team have been added to this team.
1138
1139 And when no teams can be added, a message is displayed:
1140
1141- >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')
1142+ >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
1143 >>> print extract_text(find_tag_by_id(browser.contents, 'no-candidates'))
1144 None of the teams you administer can be added to this team.
1145
1146=== modified file 'lib/lp/registry/stories/teammembership/20-managing-members.txt'
1147--- lib/lp/registry/stories/teammembership/20-managing-members.txt 2009-09-18 21:24:09 +0000
1148+++ lib/lp/registry/stories/teammembership/20-managing-members.txt 2010-01-05 17:55:34 +0000
1149@@ -28,7 +28,15 @@
1150 >>> print_members(browser.contents, 'proposedmembers')
1151 Foo Bar
1152
1153- >>> print_members(browser.contents, 'inactivemembers')
1154+Former members are only viewable by admins of the team.
1155+
1156+ >>> print find_tag_by_id(browser.contents, 'inactivemembers')
1157+ None
1158+
1159+ >>> name12_browser = setupBrowser(
1160+ ... auth="Basic test@canonical.com:test")
1161+ >>> name12_browser.open(browser.url)
1162+ >>> print_members(name12_browser.contents, 'inactivemembers')
1163 Karl Tilbury
1164 No Privileges Person
1165
1166@@ -57,12 +65,13 @@
1167 ... [launchpad]
1168 ... default_batch_size: 2
1169 ... """)
1170- >>> browser.open('http://launchpad.dev/~admins/+members?inactive_batch=2')
1171- >>> print_members(browser.contents, 'inactivemembers')
1172+ >>> admin_browser.open(
1173+ ... 'http://launchpad.dev/~admins/+members?inactive_batch=2')
1174+ >>> print_members(admin_browser.contents, 'inactivemembers')
1175 Celso Providelo
1176 David Allouche
1177- >>> browser.getLink('Next', index=2).click()
1178- >>> print_members(browser.contents, 'inactivemembers')
1179+ >>> admin_browser.getLink('Next', index=2).click()
1180+ >>> print_members(admin_browser.contents, 'inactivemembers')
1181 James Blackwell
1182 >>> config_data = config.pop('default-batch-size')
1183
1184
1185=== modified file 'lib/lp/registry/stories/teammembership/private-team.txt'
1186--- lib/lp/registry/stories/teammembership/private-team.txt 2009-10-26 21:12:49 +0000
1187+++ lib/lp/registry/stories/teammembership/private-team.txt 2010-01-05 17:55:34 +0000
1188@@ -17,7 +17,7 @@
1189 >>> person_set = getUtility(IPersonSet)
1190 >>> cprov = person_set.getByName('cprov')
1191 >>> login_person(owner)
1192- >>> priv_team.addMember(cprov, reviewer=owner)
1193+ >>> ignored = priv_team.addMember(cprov, reviewer=owner)
1194 >>> logout()
1195
1196 >>> admin_browser.open('http://launchpad.dev/~private-team')
1197
1198=== modified file 'lib/lp/registry/stories/teammembership/xx-add-member.txt'
1199--- lib/lp/registry/stories/teammembership/xx-add-member.txt 2009-10-26 14:37:31 +0000
1200+++ lib/lp/registry/stories/teammembership/xx-add-member.txt 2010-01-05 17:55:34 +0000
1201@@ -49,7 +49,7 @@
1202 >>> from canonical.launchpad.interfaces import TeamMembershipStatus
1203 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
1204 >>> login(ANONYMOUS) # login() because we need a zope interaction.
1205- >>> cprov_landscape_membership.setStatus(
1206+ >>> ignored = cprov_landscape_membership.setStatus(
1207 ... TeamMembershipStatus.DEACTIVATED, landscape_team.teamowner)
1208 >>> logout()
1209 >>> cprov_landscape_membership.syncUpdate()
1210@@ -171,44 +171,47 @@
1211 same. When an admin accepts or declines an invitation, the other admin can't
1212 take action on that invitation anymore.
1213
1214-First invite ubuntu-team to be member of the name21 team.
1215+First invite name20 to be a member of ubuntu-team.
1216
1217- >>> browser.open('http://launchpad.dev/~name21/+addmember')
1218- >>> browser.getControl('New member:').value = 'ubuntu-team'
1219+ >>> browser = setupBrowser(
1220+ ... auth='Basic colin.watson@ubuntulinux.com:test')
1221+ >>> browser.open('http://launchpad.dev/~ubuntu-team/+addmember')
1222+ >>> browser.getControl('New member:').value = 'name20'
1223 >>> browser.getControl('Add Member').click()
1224
1225 >>> for tag in find_tags_by_class(browser.contents,
1226 ... 'informational message'):
1227 ... print tag.renderContents()
1228- Ubuntu Team (ubuntu-team) has been invited to join this team.
1229+ Warty Security Team (name20) has been invited to join this team.
1230
1231 Open the invitations page with one admin browser.
1232
1233- >>> browser.open('http://launchpad.dev/~ubuntu-team/+invitation/name21')
1234+ >>> browser = setupBrowser(auth='Basic mark@example.com:test')
1235+ >>> browser.open('http://launchpad.dev/~name20/+invitation/ubuntu-team')
1236
1237 Open the same page with another admin browser.
1238
1239- >>> second_browser = setupBrowser(auth='Basic foo.bar@canonical.com:test')
1240+ >>> second_browser = setupBrowser(auth='Basic mark@example.com:test')
1241 >>> second_browser.open(
1242- ... 'http://launchpad.dev/~ubuntu-team/+invitation/name21')
1243+ ... 'http://launchpad.dev/~name20/+invitation/ubuntu-team')
1244
1245 Accept the invitation in the first browser.
1246
1247 >>> browser.getControl('Accept').click()
1248 >>> browser.url
1249- 'http://launchpad.dev/~ubuntu-team'
1250+ 'http://launchpad.dev/~name20'
1251
1252 >>> for tag in find_tags_by_class(browser.contents,
1253 ... 'informational message'):
1254 ... print tag.renderContents()
1255- This team is now a member of Hoary Gnome Team
1256+ This team is now a member of Ubuntu Team
1257
1258 Accepting the invitation in the second browser, redirects to the team page
1259 and a message is displayed.
1260
1261 >>> second_browser.getControl('Accept').click()
1262 >>> second_browser.url
1263- 'http://launchpad.dev/~ubuntu-team'
1264+ 'http://launchpad.dev/~name20'
1265
1266 >>> for tag in find_tags_by_class(second_browser.contents,
1267 ... 'informational message'):
1268@@ -233,7 +236,7 @@
1269 >>> login(ANONYMOUS) # login() because we need a zope interaction.
1270 >>> carlos_translators_membership = TeamMembership.selectOneBy(
1271 ... personID=carlos.id, teamID=ubuntu_translators.id)
1272- >>> carlos_translators_membership.setStatus(
1273+ >>> ignored = carlos_translators_membership.setStatus(
1274 ... TeamMembershipStatus.DEACTIVATED, ubuntu_translators.teamowner)
1275 >>> logout()
1276 >>> carlos_translators_membership.syncUpdate()
1277
1278=== modified file 'lib/lp/registry/stories/teammembership/xx-expire-subscription.txt'
1279--- lib/lp/registry/stories/teammembership/xx-expire-subscription.txt 2009-08-13 19:03:36 +0000
1280+++ lib/lp/registry/stories/teammembership/xx-expire-subscription.txt 2010-01-05 17:55:34 +0000
1281@@ -32,7 +32,7 @@
1282 ... personID=sampleperson.id, teamID=team.id)
1283 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
1284 >>> login(ANONYMOUS) # login() because we need a zope interaction.
1285- >>> tm.setStatus(TeamMembershipStatus.EXPIRED, team.teamowner)
1286+ >>> ignored = tm.setStatus(TeamMembershipStatus.EXPIRED, team.teamowner)
1287 >>> logout()
1288
1289 Persist the change:
1290
1291=== modified file 'lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt'
1292--- lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt 2009-12-10 16:15:21 +0000
1293+++ lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt 2010-01-05 17:55:34 +0000
1294@@ -141,7 +141,7 @@
1295 >>> login('mark@example.com')
1296 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')
1297 >>> landscape_devs = personset.getByName('landscape-developers')
1298- >>> mirror_admins.addMember(
1299+ >>> ignored = mirror_admins.addMember(
1300 ... landscape_devs, mirror_admins.teamowner, force_team_add=True)
1301 >>> membership = getUtility(ITeamMembershipSet).getByPersonAndTeam(
1302 ... landscape_devs, mirror_admins)
1303
1304=== modified file 'lib/lp/registry/stories/teammembership/xx-private-membership.txt'
1305--- lib/lp/registry/stories/teammembership/xx-private-membership.txt 2009-12-01 22:09:05 +0000
1306+++ lib/lp/registry/stories/teammembership/xx-private-membership.txt 2010-01-05 17:55:34 +0000
1307@@ -43,7 +43,7 @@
1308 <...<a href=".../~member" class="sprite person">Gold Member</a>...
1309
1310
1311- >>> find_tag_by_id(browser.contents, 'recently-applied')
1312+ >>> find_tag_by_id(browser.contents, 'recently-proposed')
1313 <...<a href=".../~no-priv" class="sprite person">No Privileges Person</a>...
1314
1315 >>> print extract_text(
1316@@ -257,9 +257,9 @@
1317 team's home page, they see the private team show up in the "Subteam of"
1318 section.
1319
1320- >>> admin_browser.open('http://launchpad.dev/~myteam/+addmember')
1321- >>> admin_browser.getControl('New member').value = 'guadamen'
1322- >>> admin_browser.getControl('Add Member').click()
1323+ >>> owner_browser.open('http://launchpad.dev/~myteam/+addmember')
1324+ >>> owner_browser.getControl('New member').value = 'guadamen'
1325+ >>> owner_browser.getControl('Add Member').click()
1326 >>> admin_browser.open(
1327 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')
1328 >>> admin_browser.getControl('Accept').click()
1329
1330=== modified file 'lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt'
1331--- lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt 2009-09-08 15:58:38 +0000
1332+++ lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt 2010-01-05 17:55:34 +0000
1333@@ -117,7 +117,8 @@
1334 >>> commercial_member = getUtility(IPersonSet).getByEmail(
1335 ... 'commercial-member@canonical.com')
1336 >>> celebs = getUtility(ILaunchpadCelebrities)
1337- >>> celebs.registry_experts.addMember(commercial_member, commercial_member)
1338+ >>> ignored = celebs.registry_experts.addMember(
1339+ ... commercial_member, commercial_member)
1340 >>> logout()
1341
1342 >>> browser.open(
1343
1344=== modified file 'lib/lp/registry/stories/webservice/xx-private-membership.txt'
1345--- lib/lp/registry/stories/webservice/xx-private-membership.txt 2009-10-01 12:30:32 +0000
1346+++ lib/lp/registry/stories/webservice/xx-private-membership.txt 2010-01-05 17:55:34 +0000
1347@@ -35,9 +35,10 @@
1348 Similarly, when a public team is a sub-team of a private team, non-members
1349 cannot see the private team in the public team's super_team's attribute.
1350
1351- >>> admin_browser.open('http://launchpad.dev/~myteam/+addmember')
1352- >>> admin_browser.getControl('New member').value = 'guadamen'
1353- >>> admin_browser.getControl('Add Member').click()
1354+ >>> owner_browser = setupBrowser(auth="Basic owner@canonical.com:test")
1355+ >>> owner_browser.open('http://launchpad.dev/~myteam/+addmember')
1356+ >>> owner_browser.getControl('New member').value = 'guadamen'
1357+ >>> owner_browser.getControl('Add Member').click()
1358 >>> admin_browser.open(
1359 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')
1360 >>> admin_browser.getControl('Accept').click()
1361
1362=== modified file 'lib/lp/registry/stories/webservice/xx-source-package.txt'
1363--- lib/lp/registry/stories/webservice/xx-source-package.txt 2009-12-05 18:37:28 +0000
1364+++ lib/lp/registry/stories/webservice/xx-source-package.txt 2010-01-05 17:55:34 +0000
1365@@ -67,7 +67,7 @@
1366 >>> login('admin@canonical.com')
1367 >>> person = factory.makePerson()
1368 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches
1369- >>> ubuntu_branches.addMember(person, ubuntu_branches.teamowner)
1370+ >>> ignored = ubuntu_branches.addMember(person, ubuntu_branches.teamowner)
1371 >>> logout()
1372
1373 Then we set the branch on the evolution hoary package:
1374
1375=== modified file 'lib/lp/registry/stories/webservice/xx-structuralsubscription.txt'
1376--- lib/lp/registry/stories/webservice/xx-structuralsubscription.txt 2009-12-05 18:37:28 +0000
1377+++ lib/lp/registry/stories/webservice/xx-structuralsubscription.txt 2010-01-05 17:55:34 +0000
1378@@ -8,7 +8,7 @@
1379 >>> eric_db = factory.makePerson(name='eric')
1380 >>> michael_db = factory.makePerson(name='michael')
1381 >>> pythons_db = factory.makeTeam(name='pythons', owner=michael_db)
1382- >>> pythons_db.addMember(eric_db, michael_db)
1383+ >>> ignored = pythons_db.addMember(eric_db, michael_db)
1384
1385 >>> fooix_db = factory.makeProduct(name='fooix', owner=eric_db)
1386 >>> fooix01_db = fooix_db.newSeries(eric_db, '0.1', 'Series 0.1')
1387
1388=== modified file 'lib/lp/registry/tests/bug-249185.txt'
1389--- lib/lp/registry/tests/bug-249185.txt 2009-04-17 10:32:16 +0000
1390+++ lib/lp/registry/tests/bug-249185.txt 2010-01-05 17:55:34 +0000
1391@@ -9,18 +9,19 @@
1392
1393 >>> login_person(person)
1394 >>> dev1 = factory.makePerson()
1395- >>> devs.addMember(dev1, person)
1396+ >>> ignored = devs.addMember(dev1, person)
1397
1398 Beta testers has lp-devs and adjutants as members.
1399
1400- >>> beta_testers.addMember(devs, person, force_team_add=True)
1401- >>> beta_testers.addMember(adjutants, person, force_team_add=True)
1402+ >>> ignored = beta_testers.addMember(devs, person, force_team_add=True)
1403+ >>> ignored = beta_testers.addMember(
1404+ ... adjutants, person, force_team_add=True)
1405 >>> dev1.hasParticipationEntryFor(beta_testers)
1406 True
1407
1408 Adjutants has lp-devs as member.
1409
1410- >>> adjutants.addMember(devs, person, force_team_add=True)
1411+ >>> ignored = adjutants.addMember(devs, person, force_team_add=True)
1412 >>> dev1.hasParticipationEntryFor(adjutants)
1413 True
1414
1415
1416=== modified file 'lib/lp/registry/tests/test_teammembership.py'
1417--- lib/lp/registry/tests/test_teammembership.py 2009-10-19 16:14:18 +0000
1418+++ lib/lp/registry/tests/test_teammembership.py 2010-01-05 17:55:34 +0000
1419@@ -546,8 +546,8 @@
1420 # Invite team2 as member of team1 and team1 as member of team2. This
1421 # is not a problem because that won't make any team an active member
1422 # of the other.
1423- self.team1.addMember(self.team2, self.foobar)
1424- self.team2.addMember(self.team1, self.foobar)
1425+ self.team1.addMember(self.team2, self.no_priv)
1426+ self.team2.addMember(self.team1, self.no_priv)
1427 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
1428 self.team1, self.team2)
1429 team2_on_team1 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
1430@@ -580,7 +580,7 @@
1431 """No status change can create cyclical participation."""
1432 # Invite team1 as a member of team3 and forcibly add team2 as member
1433 # of team1 and team3 as member of team2.
1434- self.team3.addMember(self.team1, self.foobar)
1435+ self.team3.addMember(self.team1, self.no_priv)
1436 self.team1.addMember(self.team2, self.foobar, force_team_add=True)
1437 self.team2.addMember(self.team3, self.foobar, force_team_add=True)
1438
1439@@ -593,7 +593,7 @@
1440 TeamMembershipStatus.APPROVED, self.foobar)
1441
1442 def test_invited_member_can_be_made_admin(self):
1443- self.team2.addMember(self.team1, self.foobar)
1444+ self.team2.addMember(self.team1, self.no_priv)
1445 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
1446 self.team1, self.team2)
1447 self.assertEqual(team1_on_team2.status, TeamMembershipStatus.INVITED)
1448
1449=== modified file 'lib/lp/soyuz/browser/tests/archive-views.txt'
1450--- lib/lp/soyuz/browser/tests/archive-views.txt 2009-11-09 17:59:18 +0000
1451+++ lib/lp/soyuz/browser/tests/archive-views.txt 2010-01-05 17:55:34 +0000
1452@@ -957,7 +957,7 @@
1453 buildd_secret would leak through the public buildlogs.
1454
1455 >>> login('foo.bar@canonical.com')
1456- >>> a_team.addMember(cprov, mark)
1457+ >>> ignored = a_team.addMember(cprov, mark)
1458 >>> login('celso.providelo@canonical.com')
1459
1460 >>> view = create_initialized_view(
1461@@ -1186,7 +1186,7 @@
1462 continue to be denied in the UI.
1463
1464 >>> login('foo.bar@canonical.com')
1465- >>> ubuntu.main_archive.owner.addMember(cprov, cprov)
1466+ >>> ignored = ubuntu.main_archive.owner.addMember(cprov, cprov)
1467 >>> login('celso.providelo@canonical.com')
1468
1469 >>> view = create_initialized_view(
1470
1471=== modified file 'lib/lp/soyuz/browser/tests/build-views.txt'
1472--- lib/lp/soyuz/browser/tests/build-views.txt 2009-12-11 12:59:08 +0000
1473+++ lib/lp/soyuz/browser/tests/build-views.txt 2010-01-05 17:55:34 +0000
1474@@ -153,7 +153,7 @@
1475 ... "launchpad-buildd-admins")
1476 >>> nopriv = getUtility(IPersonSet).getByName("no-priv")
1477 >>> login("foo.bar@canonical.com")
1478- >>> buildd_admins.addMember(nopriv, nopriv)
1479+ >>> ignored = buildd_admins.addMember(nopriv, nopriv)
1480
1481 >>> login("no-priv@canonical.com")
1482 >>> failed_build_view = getMultiAdapter(
1483
1484=== modified file 'lib/lp/soyuz/doc/archive.txt'
1485--- lib/lp/soyuz/doc/archive.txt 2009-12-25 07:54:31 +0000
1486+++ lib/lp/soyuz/doc/archive.txt 2010-01-05 17:55:34 +0000
1487@@ -1653,7 +1653,8 @@
1488
1489 But if we make him part of the uploader_team he'll gain access:
1490
1491- >>> uploader_team.addMember(indirect_uploader, indirect_uploader)
1492+ >>> ignored = uploader_team.addMember(
1493+ ... indirect_uploader, indirect_uploader)
1494 >>> for ppa in archive_set.getPPAsForUser(indirect_uploader):
1495 ... print ppa.displayname
1496 PPA for Celso Providelo
1497@@ -2249,7 +2250,7 @@
1498 >>> login('foo.bar@canonical.com')
1499 >>> ubuntu_security = getUtility(IPersonSet).getByName(
1500 ... 'ubuntu-security')
1501- >>> ubuntu_security.addMember(carlos, cprov)
1502+ >>> ignored = ubuntu_security.addMember(carlos, cprov)
1503
1504 >>> login('carlos@canonical.com')
1505 >>> check_permission('launchpad.Append', primary)
1506
1507=== modified file 'lib/lp/soyuz/doc/archivepermission.txt'
1508--- lib/lp/soyuz/doc/archivepermission.txt 2009-09-18 09:29:49 +0000
1509+++ lib/lp/soyuz/doc/archivepermission.txt 2010-01-05 17:55:34 +0000
1510@@ -297,7 +297,7 @@
1511 Now add "test@canonical.com" to the techboard team and log in as him.
1512
1513 >>> person = personset.getByEmail("test@canonical.com")
1514- >>> techboard.addMember(
1515+ >>> ignored = techboard.addMember(
1516 ... person, reviewer=person, status=TeamMembershipStatus.APPROVED,
1517 ... force_team_add=True)
1518 >>> login_person(person)
1519
1520=== modified file 'lib/lp/soyuz/doc/archivesubscriber.txt'
1521--- lib/lp/soyuz/doc/archivesubscriber.txt 2009-08-13 19:03:36 +0000
1522+++ lib/lp/soyuz/doc/archivesubscriber.txt 2010-01-05 17:55:34 +0000
1523@@ -448,7 +448,8 @@
1524 indirect members that are not themselves groups are included:
1525
1526 >>> launchpad_devs = getUtility(IPersonSet).getByName('launchpad')
1527- >>> launchpad_devs.addMember(team_cprov, mark, force_team_add=True)
1528+ >>> ignored = launchpad_devs.addMember(
1529+ ... team_cprov, mark, force_team_add=True)
1530 >>> subscription = mark.archive.newSubscription(
1531 ... launchpad_devs, mark, description=u"LP team too")
1532 >>> for person in subscription.getNonActiveSubscribers():
1533
1534=== modified file 'lib/lp/soyuz/doc/build-notification.txt'
1535--- lib/lp/soyuz/doc/build-notification.txt 2009-08-13 19:03:36 +0000
1536+++ lib/lp/soyuz/doc/build-notification.txt 2010-01-05 17:55:34 +0000
1537@@ -530,7 +530,7 @@
1538 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
1539 >>> team = factory.makeTeam(owner=cprov, email="team@example.com")
1540 >>> mark = failed_candidate.sourcepackagerelease.creator
1541- >>> team.addMember(mark, mark)
1542+ >>> ignored = team.addMember(mark, mark)
1543 >>> discard = pop_notifications() # Discard team join email.
1544 >>> team_ppa = factory.makeArchive(owner=team)
1545 >>> naked_candidate = removeSecurityProxy(failed_candidate)
1546
1547=== modified file 'lib/lp/soyuz/doc/build.txt'
1548--- lib/lp/soyuz/doc/build.txt 2009-11-24 07:02:21 +0000
1549+++ lib/lp/soyuz/doc/build.txt 2010-01-05 17:55:34 +0000
1550@@ -837,7 +837,7 @@
1551 >>> buildd_admin = factory.makePerson()
1552 >>> buildd_admins = getUtility(
1553 ... IPersonSet).getByName('launchpad-buildd-admins')
1554- >>> buildd_admins.addMember(buildd_admin, buildd_admin)
1555+ >>> ignored = buildd_admins.addMember(buildd_admin, buildd_admin)
1556 >>> bob_builds = bob.getBuildRecords(user=buildd_admin)
1557 >>> print_build_details(bob_builds)
1558 ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
1559@@ -845,9 +845,9 @@
1560 ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
1561 ...
1562 ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
1563- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
1564+ ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
1565 RELEASE
1566-
1567+
1568 >>> bob_builds.count()
1569 13
1570
1571
1572=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt'
1573--- lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 2009-08-31 02:52:41 +0000
1574+++ lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 2010-01-05 17:55:34 +0000
1575@@ -279,7 +279,7 @@
1576 >>> beta_testers = getUtility(ILaunchpadCelebrities).launchpad_beta_testers
1577 >>> admin = getUtility(ILaunchpadCelebrities).admin
1578 >>> name16 = getUtility(IPersonSet).getByName("name16")
1579- >>> beta_testers.addMember(name16, admin)
1580+ >>> ignored = beta_testers.addMember(name16, admin)
1581
1582 >>> foobar_archive = getUtility(IArchiveSet).new(
1583 ... distribution=ubuntutest, purpose=ArchivePurpose.PPA,
1584
1585=== modified file 'lib/lp/soyuz/doc/packageset.txt'
1586--- lib/lp/soyuz/doc/packageset.txt 2009-08-13 15:12:16 +0000
1587+++ lib/lp/soyuz/doc/packageset.txt 2010-01-05 17:55:34 +0000
1588@@ -581,7 +581,7 @@
1589
1590 Now add "test@canonical.com" to the techboard team and log in as him.
1591
1592- >>> techboard.addMember(
1593+ >>> ignored = techboard.addMember(
1594 ... person2, reviewer=person2, status=TeamMembershipStatus.APPROVED,
1595 ... force_team_add=True)
1596 >>> login_person(person2)
1597
1598=== modified file 'lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt'
1599--- lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt 2009-09-14 07:56:54 +0000
1600+++ lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt 2010-01-05 17:55:34 +0000
1601@@ -273,7 +273,7 @@
1602 >>> login('foo.bar@canonical.com')
1603 >>> foobar = getUtility(IPersonSet).getByName('name16')
1604 >>> mark = getUtility(IPersonSet).getByName('mark')
1605- >>> launchpad.addMember(mark, foobar)
1606+ >>> ignored = launchpad.addMember(mark, foobar)
1607 >>> import transaction
1608 >>> transaction.commit()
1609 >>> logout()
1610
1611=== modified file 'lib/lp/soyuz/stories/soyuz/xx-private-builds.txt'
1612--- lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2009-09-17 14:45:15 +0000
1613+++ lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2010-01-05 17:55:34 +0000
1614@@ -51,7 +51,7 @@
1615 ... IPersonSet).getByName("launchpad-buildd-admins")
1616 >>> from lp.registry.interfaces.person import (
1617 ... TeamMembershipStatus)
1618- >>> buildd_admins.addMember(
1619+ >>> ignored = buildd_admins.addMember(
1620 ... name12, reviewer=name12, status=TeamMembershipStatus.APPROVED)
1621
1622 >>> flush_database_updates()
1623
1624=== modified file 'lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt'
1625--- lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt 2009-09-19 08:30:29 +0000
1626+++ lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt 2010-01-05 17:55:34 +0000
1627@@ -97,7 +97,7 @@
1628 >>> oofy = factory.makePerson(email='oofy@drones.example.com',
1629 ... name='oofy', password='test', displayname='Oofy Prosser')
1630 >>> rosetta_admins = personset.getByName('rosetta-admins')
1631- >>> rosetta_admins.addMember(oofy, carlos)
1632+ >>> ignored = rosetta_admins.addMember(oofy, carlos)
1633
1634 >>> gussie = factory.makePerson(email='gussie@drones.example.com',
1635 ... name='gussie', password='test', displayname='Gussie Fink-Nottle')