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
=== modified file 'lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt'
--- lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt 2009-09-16 08:11:22 +0000
+++ lib/canonical/launchpad/pagetests/standalone/xx-beta-testers-redirection.txt 2010-01-05 17:55:34 +0000
@@ -239,7 +239,7 @@
239 >>> foo_bar = getUtility(IPersonSet).getByName('name16')239 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
240 >>> launchpad_beta_testers = getUtility(240 >>> launchpad_beta_testers = getUtility(
241 ... ILaunchpadCelebrities).launchpad_beta_testers241 ... ILaunchpadCelebrities).launchpad_beta_testers
242 >>> launchpad_beta_testers.addMember(foo_bar, reviewer=foo_bar)242 >>> ignored = launchpad_beta_testers.addMember(foo_bar, reviewer=foo_bar)
243 >>> foo_bar.inTeam(launchpad_beta_testers)243 >>> foo_bar.inTeam(launchpad_beta_testers)
244 True244 True
245245
246246
=== modified file 'lib/lp/answers/doc/person.txt'
--- lib/lp/answers/doc/person.txt 2009-04-17 10:32:16 +0000
+++ lib/lp/answers/doc/person.txt 2010-01-05 17:55:34 +0000
@@ -279,7 +279,7 @@
279contact through his team membership.279contact through his team membership.
280280
281 >>> landscape_team = personset.getByName("landscape-developers")281 >>> landscape_team = personset.getByName("landscape-developers")
282 >>> landscape_team.addMember(no_priv_raw, foo_bar_raw)282 >>> ignored = landscape_team.addMember(no_priv_raw, foo_bar_raw)
283 >>> no_priv_raw.inTeam(landscape_team)283 >>> no_priv_raw.inTeam(landscape_team)
284 True284 True
285285
@@ -301,7 +301,7 @@
301 >>> translator_team = personset.getByName('ubuntu-translators')301 >>> translator_team = personset.getByName('ubuntu-translators')
302 >>> no_priv_raw.inTeam(translator_team)302 >>> no_priv_raw.inTeam(translator_team)
303 False303 False
304 >>> translator_team.addMember(landscape_team, carlos_raw)304 >>> ignored = translator_team.addMember(landscape_team, carlos_raw)
305305
306 # We need to accept the invitation sent by the addMember() call in306 # We need to accept the invitation sent by the addMember() call in
307 # order to make landscape_team an actual member of translator_team.307 # order to make landscape_team an actual member of translator_team.
308308
=== modified file 'lib/lp/bugs/browser/tests/bug-views.txt'
--- lib/lp/bugs/browser/tests/bug-views.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/browser/tests/bug-views.txt 2010-01-05 17:55:34 +0000
@@ -710,7 +710,7 @@
710People in the team get to see the comments.710People in the team get to see the comments.
711711
712 >>> login('foo.bar@canonical.com')712 >>> login('foo.bar@canonical.com')
713 >>> syncing_team.addMember(no_priv, no_priv)713 >>> ignored = syncing_team.addMember(no_priv, no_priv)
714714
715 >>> login('no-priv@canonical.com')715 >>> login('no-priv@canonical.com')
716 >>> view = BugTaskView(bug.bugtasks[0], LaunchpadTestRequest())716 >>> view = BugTaskView(bug.bugtasks[0], LaunchpadTestRequest())
717717
=== modified file 'lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt'
--- lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/doc/bugnotification-comment-syncing-team.txt 2010-01-05 17:55:34 +0000
@@ -64,7 +64,7 @@
64Members of the syncing team will get the notifications.64Members of the syncing team will get the notifications.
6565
66 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')66 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
67 >>> syncing_team.addMember(no_priv, no_priv)67 >>> ignored = syncing_team.addMember(no_priv, no_priv)
68 >>> transaction.commit()68 >>> transaction.commit()
6969
70 >>> LaunchpadZopelessLayer.switchDbUser('bugnotification')70 >>> LaunchpadZopelessLayer.switchDbUser('bugnotification')
7171
=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
--- lib/lp/bugs/doc/bugnotification-sending.txt 2009-12-05 18:37:28 +0000
+++ lib/lp/bugs/doc/bugnotification-sending.txt 2010-01-05 17:55:34 +0000
@@ -1280,7 +1280,8 @@
1280 ... displayname='Concise Team Person',1280 ... displayname='Concise Team Person',
1281 ... email='conciseteam@example.com')1281 ... email='conciseteam@example.com')
1282 >>> concise_team_person.verbose_bugnotifications = True1282 >>> concise_team_person.verbose_bugnotifications = True
1283 >>> concise_team.addMember(concise_team_person, concise_team_person)1283 >>> ignored = concise_team.addMember(
1284 ... concise_team_person, concise_team_person)
1284 >>> bug.subscribe(concise_team, concise_team_person)1285 >>> bug.subscribe(concise_team, concise_team_person)
1285 <BugSubscription...>1286 <BugSubscription...>
12861287
@@ -1294,7 +1295,8 @@
1294 ... displayname='Verbose Team Person',1295 ... displayname='Verbose Team Person',
1295 ... email='verboseteam@example.com')1296 ... email='verboseteam@example.com')
1296 >>> verbose_team_person.verbose_bugnotifications = False1297 >>> verbose_team_person.verbose_bugnotifications = False
1297 >>> verbose_team.addMember(verbose_team_person, verbose_team_person)1298 >>> ignored = verbose_team.addMember(
1299 ... verbose_team_person, verbose_team_person)
1298 >>> bug.subscribe(verbose_team, verbose_team_person)1300 >>> bug.subscribe(verbose_team, verbose_team_person)
1299 <BugSubscription...>1301 <BugSubscription...>
13001302
13011303
=== modified file 'lib/lp/bugs/doc/bugtask.txt'
--- lib/lp/bugs/doc/bugtask.txt 2009-08-27 07:58:37 +0000
+++ lib/lp/bugs/doc/bugtask.txt 2010-01-05 17:55:34 +0000
@@ -959,7 +959,8 @@
959Team *is* subscribed to the bug, No Privileges Person will see the private bug.959Team *is* subscribed to the bug, No Privileges Person will see the private bug.
960960
961 >>> login("mark@example.com")961 >>> login("mark@example.com")
962 >>> ubuntu_team.addMember(no_priv, reviewer=ubuntu_team.teamowner)962 >>> ignored = ubuntu_team.addMember(
963 ... no_priv, reviewer=ubuntu_team.teamowner)
963964
964 >>> login("no-priv@canonical.com")965 >>> login("no-priv@canonical.com")
965 >>> params = BugTaskSearchParams(966 >>> params = BugTaskSearchParams(
966967
=== modified file 'lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt'
--- lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt 2009-09-02 12:33:41 +0000
+++ lib/lp/bugs/stories/bugwatches/xx-bugwatch-comments.txt 2010-01-05 17:55:34 +0000
@@ -55,7 +55,7 @@
55 >>> foo_bar = getUtility(IPersonSet).getByName('name16')55 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
56 >>> launchpad_beta_testers = getUtility(56 >>> launchpad_beta_testers = getUtility(
57 ... ILaunchpadCelebrities).launchpad_beta_testers57 ... ILaunchpadCelebrities).launchpad_beta_testers
58 >>> launchpad_beta_testers.addMember(mark, reviewer=foo_bar)58 >>> ignored = launchpad_beta_testers.addMember(mark, reviewer=foo_bar)
59 >>> mark.inTeam(launchpad_beta_testers)59 >>> mark.inTeam(launchpad_beta_testers)
60 True60 True
6161
6262
=== modified file 'lib/lp/code/stories/branches/xx-branch-deletion.txt'
--- lib/lp/code/stories/branches/xx-branch-deletion.txt 2009-09-23 14:40:53 +0000
+++ lib/lp/code/stories/branches/xx-branch-deletion.txt 2010-01-05 17:55:34 +0000
@@ -84,7 +84,7 @@
84 >>> login(ANONYMOUS)84 >>> login(ANONYMOUS)
85 >>> name12 = getUtility(IPersonSet).getByName('name12')85 >>> name12 = getUtility(IPersonSet).getByName('name12')
86 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches86 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches
87 >>> removeSecurityProxy(ubuntu_branches).addMember(87 >>> ignored = removeSecurityProxy(ubuntu_branches).addMember(
88 ... name12, ubuntu_branches.teamowner)88 ... name12, ubuntu_branches.teamowner)
89 >>> login_person(name12)89 >>> login_person(name12)
90 >>> branch = factory.makePackageBranch(owner=name12)90 >>> branch = factory.makePackageBranch(owner=name12)
9191
=== modified file 'lib/lp/code/stories/feeds/xx-revision-atom.txt'
--- lib/lp/code/stories/feeds/xx-revision-atom.txt 2009-07-09 05:12:34 +0000
+++ lib/lp/code/stories/feeds/xx-revision-atom.txt 2010-01-05 17:55:34 +0000
@@ -54,7 +54,7 @@
5454
55 >>> login_person(mike)55 >>> login_person(mike)
56 >>> team = factory.makeTeam(mike, 'The M Team', name='m-team')56 >>> team = factory.makeTeam(mike, 'The M Team', name='m-team')
57 >>> team.addMember(mary, mike)57 >>> ignored = team.addMember(mary, mike)
58 >>> from lp.code.interfaces.revision import IRevisionSet58 >>> from lp.code.interfaces.revision import IRevisionSet
59 >>> from zope.component import getUtility59 >>> from zope.component import getUtility
60 >>> revision_set = getUtility(IRevisionSet)60 >>> revision_set = getUtility(IRevisionSet)
6161
=== 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-05 17:55:34 +0000
@@ -993,9 +993,11 @@
993 assert newmember != self.context, (993 assert newmember != self.context, (
994 "Can't add team to itself: %s" % newmember)994 "Can't add team to itself: %s" % newmember)
995995
996 self.context.addMember(newmember, reviewer=self.user,996 changed, new_status = self.context.addMember(
997 status=TeamMembershipStatus.APPROVED)997 newmember, reviewer=self.user,
998 if newmember.isTeam():998 status=TeamMembershipStatus.APPROVED)
999
1000 if new_status == TeamMembershipStatus.INVITED:
999 msg = "%s has been invited to join this team." % (1001 msg = "%s has been invited to join this team." % (
1000 newmember.unique_displayname)1002 newmember.unique_displayname)
1001 else:1003 else:
10021004
=== modified file 'lib/lp/registry/browser/tests/peoplemerge-views.txt'
--- lib/lp/registry/browser/tests/peoplemerge-views.txt 2009-07-27 20:53:27 +0000
+++ lib/lp/registry/browser/tests/peoplemerge-views.txt 2010-01-05 17:55:34 +0000
@@ -38,7 +38,7 @@
38 >>> parent_team = factory.makeTeam()38 >>> parent_team = factory.makeTeam()
39 >>> child_team = factory.makeTeam(name='child-team')39 >>> child_team = factory.makeTeam(name='child-team')
40 >>> random_team = factory.makeTeam()40 >>> random_team = factory.makeTeam()
41 >>> parent_team.addMember(41 >>> ignored = parent_team.addMember(
42 ... child_team, reviewer=parent_team.teamowner, force_team_add=True)42 ... child_team, reviewer=parent_team.teamowner, force_team_add=True)
43 >>> form = {'field.dupe_person': child_team.name,43 >>> form = {'field.dupe_person': child_team.name,
44 ... 'field.target_person': random_team.name,44 ... 'field.target_person': random_team.name,
4545
=== modified file 'lib/lp/registry/browser/tests/person-views.txt'
--- lib/lp/registry/browser/tests/person-views.txt 2009-12-23 16:17:12 +0000
+++ lib/lp/registry/browser/tests/person-views.txt 2010-01-05 17:55:34 +0000
@@ -911,7 +911,7 @@
911911
912 >>> login("admin@canonical.com")912 >>> login("admin@canonical.com")
913 >>> team = factory.makeTeam()913 >>> team = factory.makeTeam()
914 >>> team.addMember(sample_person, sample_person)914 >>> ignored = team.addMember(sample_person, sample_person)
915 >>> ppa = factory.makeArchive(distribution=ubuntu, owner=team)915 >>> ppa = factory.makeArchive(distribution=ubuntu, owner=team)
916916
917 >>> login(ANONYMOUS)917 >>> login(ANONYMOUS)
918918
=== modified file 'lib/lp/registry/browser/tests/product-views.txt'
--- lib/lp/registry/browser/tests/product-views.txt 2009-11-23 14:52:25 +0000
+++ lib/lp/registry/browser/tests/product-views.txt 2010-01-05 17:55:34 +0000
@@ -142,7 +142,7 @@
142 >>> commercial_member = getUtility(IPersonSet).getByEmail(142 >>> commercial_member = getUtility(IPersonSet).getByEmail(
143 ... 'commercial-member@canonical.com')143 ... 'commercial-member@canonical.com')
144 >>> registry_experts = getUtility(IPersonSet).getByName('registry')144 >>> registry_experts = getUtility(IPersonSet).getByName('registry')
145 >>> registry_experts.addMember(commercial_member, reviewer=mark)145 >>> ignored = registry_experts.addMember(commercial_member, reviewer=mark)
146 >>> login('commercial-member@canonical.com')146 >>> login('commercial-member@canonical.com')
147 >>> view = create_initialized_view(firefox, name='+review-license')147 >>> view = create_initialized_view(firefox, name='+review-license')
148 >>> print view.label148 >>> print view.label
149149
=== modified file 'lib/lp/registry/browser/tests/projectgroupset-views.txt'
--- lib/lp/registry/browser/tests/projectgroupset-views.txt 2009-09-12 06:00:05 +0000
+++ lib/lp/registry/browser/tests/projectgroupset-views.txt 2010-01-05 17:55:34 +0000
@@ -44,7 +44,7 @@
4444
45 >>> registry_member = factory.makePerson()45 >>> registry_member = factory.makePerson()
46 >>> login('foo.bar@canonical.com')46 >>> login('foo.bar@canonical.com')
47 >>> registry.addMember(registry_member, registry.teamowner)47 >>> ignored = registry.addMember(registry_member, registry.teamowner)
48 >>> registry_member.inTeam(registry)48 >>> registry_member.inTeam(registry)
49 True49 True
5050
5151
=== modified file 'lib/lp/registry/browser/tests/team-views.txt'
--- lib/lp/registry/browser/tests/team-views.txt 2009-11-25 23:20:08 +0000
+++ lib/lp/registry/browser/tests/team-views.txt 2010-01-05 17:55:34 +0000
@@ -33,7 +33,7 @@
33 >>> salgado = person_set.getByName('salgado')33 >>> salgado = person_set.getByName('salgado')
34 >>> mark = person_set.getByName('mark')34 >>> mark = person_set.getByName('mark')
35 >>> login('foo.bar@canonical.com')35 >>> login('foo.bar@canonical.com')
36 >>> ubuntu_team.addMember(salgado, reviewer=mark)36 >>> ignored = ubuntu_team.addMember(salgado, reviewer=mark)
3737
38 >>> team_home = create_initialized_view(ubuntu_team, '+index')38 >>> team_home = create_initialized_view(ubuntu_team, '+index')
39 >>> for member in team_home.recently_approved_members:39 >>> for member in team_home.recently_approved_members:
@@ -125,7 +125,7 @@
125125
126 >>> london_member = factory.makePerson(126 >>> london_member = factory.makePerson(
127 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')127 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')
128 >>> context.addMember(london_member, mark)128 >>> ignored = context.addMember(london_member, mark)
129 >>> context.mapped_participants_count129 >>> context.mapped_participants_count
130 1130 1
131 >>> view = create_initialized_view(context, '+map')131 >>> view = create_initialized_view(context, '+map')
@@ -139,7 +139,7 @@
139139
140 >>> brazil_member = factory.makePerson(140 >>> brazil_member = factory.makePerson(
141 ... latitude=-23.60, longitude=-46.64, time_zone='America/Sao_Paulo')141 ... latitude=-23.60, longitude=-46.64, time_zone='America/Sao_Paulo')
142 >>> context.addMember(brazil_member, mark)142 >>> ignored = context.addMember(brazil_member, mark)
143 >>> context.mapped_participants_count143 >>> context.mapped_participants_count
144 2144 2
145 >>> view = create_initialized_view(context, '+map')145 >>> view = create_initialized_view(context, '+map')
@@ -153,7 +153,7 @@
153153
154 >>> london_member2 = factory.makePerson(154 >>> london_member2 = factory.makePerson(
155 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')155 ... latitude=51.49, longitude=-0.13, time_zone='Europe/London')
156 >>> context.addMember(london_member2, mark)156 >>> ignored = context.addMember(london_member2, mark)
157 >>> context.mapped_participants_count157 >>> context.mapped_participants_count
158 3158 3
159 >>> view = create_initialized_view(context, '+map')159 >>> view = create_initialized_view(context, '+map')
160160
=== modified file 'lib/lp/registry/browser/tests/teammembership-views.txt'
--- lib/lp/registry/browser/tests/teammembership-views.txt 2010-01-05 17:55:30 +0000
+++ lib/lp/registry/browser/tests/teammembership-views.txt 2010-01-05 17:55:34 +0000
@@ -62,8 +62,7 @@
62 >>> from lp.registry.browser.person import TeamInvitationView62 >>> from lp.registry.browser.person import TeamInvitationView
6363
64 >>> login_person(team_owner)64 >>> login_person(team_owner)
65 >>> super_team.addMember(team, team_owner)65 >>> ignored = super_team.addMember(team, team_owner)
66 True
67 >>> membership = membership_set.getByPersonAndTeam(team, super_team)66 >>> membership = membership_set.getByPersonAndTeam(team, super_team)
68 >>> login_person(team.teamowner)67 >>> login_person(team.teamowner)
69 >>> view = TeamInvitationView(membership, request)68 >>> view = TeamInvitationView(membership, request)
7069
=== modified file 'lib/lp/registry/doc/announcement.txt'
--- lib/lp/registry/doc/announcement.txt 2009-08-13 19:03:36 +0000
+++ lib/lp/registry/doc/announcement.txt 2010-01-05 17:55:34 +0000
@@ -32,7 +32,7 @@
32 >>> login('foo.bar@canonical.com')32 >>> login('foo.bar@canonical.com')
33 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities33 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities
34 >>> beta = getUtility(ILaunchpadCelebrities).launchpad_beta_testers34 >>> beta = getUtility(ILaunchpadCelebrities).launchpad_beta_testers
35 >>> beta.addMember(mark, mark)35 >>> ignored = beta.addMember(mark, mark)
36 >>> from canonical.database.sqlbase import flush_database_updates36 >>> from canonical.database.sqlbase import flush_database_updates
37 >>> flush_database_updates()37 >>> flush_database_updates()
38 >>> logout()38 >>> logout()
3939
=== modified file 'lib/lp/registry/doc/commercialsubscription.txt'
--- lib/lp/registry/doc/commercialsubscription.txt 2009-09-16 20:08:36 +0000
+++ lib/lp/registry/doc/commercialsubscription.txt 2010-01-05 17:55:34 +0000
@@ -550,7 +550,7 @@
550 >>> registry_member = factory.makePerson()550 >>> registry_member = factory.makePerson()
551 >>> celebs = getUtility(ILaunchpadCelebrities)551 >>> celebs = getUtility(ILaunchpadCelebrities)
552 >>> registry = celebs.registry_experts552 >>> registry = celebs.registry_experts
553 >>> registry.addMember(registry_member, registry.teamowner)553 >>> ignored = registry.addMember(registry_member, registry.teamowner)
554 >>> logout()554 >>> logout()
555555
556 >>> login_person(registry_member)556 >>> login_person(registry_member)
557557
=== modified file 'lib/lp/registry/doc/mailinglist-email-notification.txt'
--- lib/lp/registry/doc/mailinglist-email-notification.txt 2009-05-12 08:11:06 +0000
+++ lib/lp/registry/doc/mailinglist-email-notification.txt 2010-01-05 17:55:34 +0000
@@ -10,7 +10,7 @@
10 >>> salgado = getUtility(IPersonSet).getByName('salgado')10 >>> salgado = getUtility(IPersonSet).getByName('salgado')
1111
12 >>> from lp.registry.tests.mailinglists_helper import (12 >>> from lp.registry.tests.mailinglists_helper import (
13 ... new_team, new_list_for_team)13 ... new_team, new_list_for_team)
1414
15 # login() as an admin so that we can call IPerson.join() on any15 # login() as an admin so that we can call IPerson.join() on any
16 # person/team we want.16 # person/team we want.
@@ -33,7 +33,8 @@
33 >>> list_one.status.name33 >>> list_one.status.name
34 'ACTIVE'34 'ACTIVE'
3535
36 >>> transaction.commit() # Send the emails.36 # Send the emails.
37 >>> transaction.commit()
3738
38Both Anne and No Privileges Person receive the notifications, Anne as a39Both Anne and No Privileges Person receive the notifications, Anne as a
39newly subscribed member and No Privileges Person as the owner of the40newly subscribed member and No Privileges Person as the owner of the
@@ -89,7 +90,7 @@
8990
90 >>> super_team = new_team('super-team', with_list=False)91 >>> super_team = new_team('super-team', with_list=False)
91 >>> sub_team = new_team('sub-team', with_list=False)92 >>> sub_team = new_team('sub-team', with_list=False)
92 >>> super_team.addMember(sub_team, salgado, force_team_add=True)93 >>> ignored = super_team.addMember(sub_team, salgado, force_team_add=True)
93 >>> anne.join(super_team)94 >>> anne.join(super_team)
94 >>> lars = factory.makePersonByName('Lars')95 >>> lars = factory.makePersonByName('Lars')
95 >>> lars.join(sub_team)96 >>> lars.join(sub_team)
@@ -120,7 +121,8 @@
120 >>> super_list.status.name121 >>> super_list.status.name
121 'ACTIVE'122 'ACTIVE'
122123
123 >>> transaction.commit() # Send the emails.124 # Send the emails.
125 >>> transaction.commit()
124 >>> len(stub.test_emails)126 >>> len(stub.test_emails)
125 4127 4
126 >>> print_emails(include_reply_to=True)128 >>> print_emails(include_reply_to=True)
@@ -220,6 +222,7 @@
220 >>> renewed_list.status.name222 >>> renewed_list.status.name
221 'ACTIVE'223 'ACTIVE'
222224
223 >>> transaction.commit() # Send any outstanding emails.225 # Send any outstanding emails.
226 >>> transaction.commit()
224 >>> len(stub.test_emails)227 >>> len(stub.test_emails)
225 0228 0
226229
=== modified file 'lib/lp/registry/doc/mailinglist-subscriptions.txt'
--- lib/lp/registry/doc/mailinglist-subscriptions.txt 2009-05-06 15:13:39 +0000
+++ lib/lp/registry/doc/mailinglist-subscriptions.txt 2010-01-05 17:55:34 +0000
@@ -293,7 +293,7 @@
293 ... 'sub-team', team_owner)293 ... 'sub-team', team_owner)
294 >>> team_names.extend((super_team.name, sub_team.name))294 >>> team_names.extend((super_team.name, sub_team.name))
295295
296 >>> super_team.addMember(sub_team, salgado, force_team_add=True)296 >>> ignored = super_team.addMember(sub_team, salgado, force_team_add=True)
297 >>> lars = factory.makePersonByName('Lars')297 >>> lars = factory.makePersonByName('Lars')
298 >>> lars.join(super_team)298 >>> lars.join(super_team)
299 >>> lars.join(sub_team)299 >>> lars.join(sub_team)
@@ -333,7 +333,7 @@
333 ... 'team-three', team_owner)333 ... 'team-three', team_owner)
334 >>> team_names.append(team_three.name)334 >>> team_names.append(team_three.name)
335335
336 >>> team_one.addMember(team_three, salgado, force_team_add=True)336 >>> ignored = team_one.addMember(team_three, salgado, force_team_add=True)
337 >>> dirk = factory.makePersonByName('Dirk')337 >>> dirk = factory.makePersonByName('Dirk')
338 >>> dirk.join(team_two)338 >>> dirk.join(team_two)
339 >>> dirk.join(team_three)339 >>> dirk.join(team_three)
@@ -714,7 +714,7 @@
714 >>> team_five = factory.makeTeam(name='team-five', owner=team_owner)714 >>> team_five = factory.makeTeam(name='team-five', owner=team_owner)
715 >>> team_names.append(team_five.name)715 >>> team_names.append(team_five.name)
716716
717 >>> team_one.addMember(team_five, salgado, force_team_add=True)717 >>> ignored = team_one.addMember(team_five, salgado, force_team_add=True)
718 >>> gwen = factory.makePersonByName('Gwen')718 >>> gwen = factory.makePersonByName('Gwen')
719 >>> hank = factory.makePersonByName('Hank')719 >>> hank = factory.makePersonByName('Hank')
720 >>> iona = factory.makePersonByName('Iona')720 >>> iona = factory.makePersonByName('Iona')
721721
=== modified file 'lib/lp/registry/doc/mailinglists.txt'
--- lib/lp/registry/doc/mailinglists.txt 2009-12-03 20:28:54 +0000
+++ lib/lp/registry/doc/mailinglists.txt 2010-01-05 17:55:34 +0000
@@ -82,7 +82,8 @@
82 >>> from canonical.launchpad.interfaces import TeamMembershipStatus82 >>> from canonical.launchpad.interfaces import TeamMembershipStatus
83 >>> login('foo.bar@canonical.com')83 >>> login('foo.bar@canonical.com')
84 >>> bart = factory.makePersonByName('Bart')84 >>> bart = factory.makePersonByName('Bart')
85 >>> team_two.addMember(anne, bart, status=TeamMembershipStatus.ADMIN)85 >>> ignored = team_two.addMember(
86 ... anne, bart, status=TeamMembershipStatus.ADMIN)
86 >>> login(ANONYMOUS)87 >>> login(ANONYMOUS)
87 >>> list_two = list_set.new(team_two, anne)88 >>> list_two = list_set.new(team_two, anne)
88 >>> list_two89 >>> list_two
8990
=== modified file 'lib/lp/registry/doc/person-merge.txt'
--- lib/lp/registry/doc/person-merge.txt 2009-12-07 16:07:43 +0000
+++ lib/lp/registry/doc/person-merge.txt 2010-01-05 17:55:34 +0000
@@ -42,9 +42,9 @@
42 >>> ubuntu_team.teamowner = marilize42 >>> ubuntu_team.teamowner = marilize
4343
44 >>> ubuntu_translators = personset.getByName('ubuntu-translators')44 >>> ubuntu_translators = personset.getByName('ubuntu-translators')
45 >>> ubuntu_translators.addMember(marilize, marilize)45 >>> ignored = ubuntu_translators.addMember(marilize, marilize)
46 >>> rosetta_admins = personset.getByName('rosetta-admins')46 >>> rosetta_admins = personset.getByName('rosetta-admins')
47 >>> rosetta_admins.addMember(marilize, marilize)47 >>> ignored = rosetta_admins.addMember(marilize, marilize)
4848
49Karma gets reassigned to the person we merge into. Let's assign karma to49Karma gets reassigned to the person we merge into. Let's assign karma to
50Marilize and save it for later comparison.50Marilize and save it for later comparison.
@@ -348,7 +348,7 @@
348 >>> from canonical.launchpad.interfaces import IPollSubset, PollSecrecy348 >>> from canonical.launchpad.interfaces import IPollSubset, PollSecrecy
349 >>> test_team = personset.newTeam(sample, 'test-team', 'Test team')349 >>> test_team = personset.newTeam(sample, 'test-team', 'Test team')
350 >>> launchpad_devs = personset.getByName('launchpad')350 >>> launchpad_devs = personset.getByName('launchpad')
351 >>> launchpad_devs.addMember(351 >>> ignored = launchpad_devs.addMember(
352 ... test_team, reviewer=launchpad_devs.teamowner, force_team_add=True)352 ... test_team, reviewer=launchpad_devs.teamowner, force_team_add=True)
353 >>> today = datetime.now(pytz.timezone('UTC'))353 >>> today = datetime.now(pytz.timezone('UTC'))
354 >>> tomorrow = today + timedelta(days=1)354 >>> tomorrow = today + timedelta(days=1)
355355
=== modified file 'lib/lp/registry/doc/person.txt'
--- lib/lp/registry/doc/person.txt 2009-12-03 20:00:43 +0000
+++ lib/lp/registry/doc/person.txt 2010-01-05 17:55:34 +0000
@@ -482,7 +482,7 @@
482And we can even add other members to our new team!482And we can even add other members to our new team!
483483
484 >>> login('foo.bar@canonical.com')484 >>> login('foo.bar@canonical.com')
485 >>> not_a_person.addMember(lifeless, reviewer=ddaa)485 >>> ignored = not_a_person.addMember(lifeless, reviewer=ddaa)
486 >>> login(ANONYMOUS)486 >>> login(ANONYMOUS)
487 >>> [member.name for member in not_a_person.activemembers]487 >>> [member.name for member in not_a_person.activemembers]
488 [u'ddaa', u'lifeless']488 [u'ddaa', u'lifeless']
@@ -1125,7 +1125,7 @@
1125 >>> registry_member = factory.makePerson()1125 >>> registry_member = factory.makePerson()
1126 >>> celebs = getUtility(ILaunchpadCelebrities)1126 >>> celebs = getUtility(ILaunchpadCelebrities)
1127 >>> registry = celebs.registry_experts1127 >>> registry = celebs.registry_experts
1128 >>> registry.addMember(registry_member, registry.teamowner)1128 >>> ignored = registry.addMember(registry_member, registry.teamowner)
1129 >>> logout()1129 >>> logout()
11301130
1131 >>> login_person(registry_member)1131 >>> login_person(registry_member)
11321132
=== modified file 'lib/lp/registry/doc/private-team-visibility.txt'
--- lib/lp/registry/doc/private-team-visibility.txt 2010-01-04 23:17:19 +0000
+++ lib/lp/registry/doc/private-team-visibility.txt 2010-01-05 17:55:34 +0000
@@ -17,7 +17,7 @@
17 >>> priv_team = factory.makeTeam(owner=priv_owner, name="priv-team",17 >>> priv_team = factory.makeTeam(owner=priv_owner, name="priv-team",
18 ... visibility=PersonVisibility.PRIVATE)18 ... visibility=PersonVisibility.PRIVATE)
19 >>> login_person(priv_owner)19 >>> login_person(priv_owner)
20 >>> priv_team.addMember(priv_member, reviewer=priv_owner)20 >>> ignored = priv_team.addMember(priv_member, reviewer=priv_owner)
2121
22The team owner can see the membership.22The team owner can see the membership.
2323
@@ -57,7 +57,7 @@
57 >>> pub_member = factory.makePerson(name="pub-member")57 >>> pub_member = factory.makePerson(name="pub-member")
58 >>> pub_team = factory.makeTeam(owner=pub_owner, name="pubteam")58 >>> pub_team = factory.makeTeam(owner=pub_owner, name="pubteam")
59 >>> login_person(pub_owner)59 >>> login_person(pub_owner)
60 >>> pub_team.addMember(pub_member, reviewer=pub_owner)60 >>> ignored = pub_team.addMember(pub_member, reviewer=pub_owner)
6161
62At this point the public team owner cannot see the priv-team's bits.62At this point the public team owner cannot see the priv-team's bits.
6363
@@ -67,7 +67,7 @@
67 Unauthorized: (<Person at ... priv-team (Priv Team)>, 'name', 'launchpad.View')67 Unauthorized: (<Person at ... priv-team (Priv Team)>, 'name', 'launchpad.View')
6868
69 >>> login_person(priv_owner)69 >>> login_person(priv_owner)
70 >>> priv_team.addMember(pub_team, reviewer=priv_owner)70 >>> ignored = priv_team.addMember(pub_team, reviewer=priv_owner)
7171
72The public team is not yet a member of the priv-team.72The public team is not yet a member of the priv-team.
7373
7474
=== modified file 'lib/lp/registry/doc/teammembership-email-notification.txt'
--- lib/lp/registry/doc/teammembership-email-notification.txt 2010-01-05 17:55:30 +0000
+++ lib/lp/registry/doc/teammembership-email-notification.txt 2010-01-05 17:55:34 +0000
@@ -227,8 +227,7 @@
227227
228 >>> cprov = personset.getByName('cprov')228 >>> cprov = personset.getByName('cprov')
229 >>> marilize = personset.getByName('marilize')229 >>> marilize = personset.getByName('marilize')
230 >>> ubuntu_team.addMember(marilize, reviewer=cprov)230 >>> ignored = ubuntu_team.addMember(marilize, reviewer=cprov)
231 True
232 >>> transaction.commit()231 >>> transaction.commit()
233 >>> len(stub.test_emails)232 >>> len(stub.test_emails)
234 6233 6
@@ -277,8 +276,7 @@
277 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')276 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')
278 >>> mirror_admins.getTeamAdminsEmailAddresses()277 >>> mirror_admins.getTeamAdminsEmailAddresses()
279 ['mark@example.com']278 ['mark@example.com']
280 >>> ubuntu_team.addMember(mirror_admins, reviewer=cprov)279 >>> ignored = ubuntu_team.addMember(mirror_admins, reviewer=cprov)
281 True
282 >>> transaction.commit()280 >>> transaction.commit()
283 >>> len(stub.test_emails)281 >>> len(stub.test_emails)
284 1282 1
@@ -329,8 +327,7 @@
329Similarly, a notification is sent if the invitation is declined.327Similarly, a notification is sent if the invitation is declined.
330328
331 >>> landscape = personset.getByName('landscape-developers')329 >>> landscape = personset.getByName('landscape-developers')
332 >>> ubuntu_team.addMember(landscape, reviewer=cprov)330 >>> ignored = ubuntu_team.addMember(landscape, reviewer=cprov)
333 True
334331
335 # Reset stub.test_emails as we don't care about the notification triggered332 # Reset stub.test_emails as we don't care about the notification triggered
336 # by the addMember() call.333 # by the addMember() call.
@@ -363,8 +360,8 @@
363passing force_team_add=True to the addMember() method.360passing force_team_add=True to the addMember() method.
364361
365 >>> launchpad = personset.getByName('launchpad')362 >>> launchpad = personset.getByName('launchpad')
366 >>> ubuntu_team.addMember(launchpad, reviewer=cprov, force_team_add=True)363 >>> ignored = ubuntu_team.addMember(
367 True364 ... launchpad, reviewer=cprov, force_team_add=True)
368 >>> flush_database_updates()365 >>> flush_database_updates()
369 >>> transaction.commit()366 >>> transaction.commit()
370 >>> len(stub.test_emails)367 >>> len(stub.test_emails)
@@ -854,8 +851,7 @@
854 >>> dummy = pop_notifications()851 >>> dummy = pop_notifications()
855 >>> member = factory.makePerson(852 >>> member = factory.makePerson(
856 ... name='team-member', email='team-member@example.com')853 ... name='team-member', email='team-member@example.com')
857 >>> team_one.addMember(member, owner)854 >>> ignored = team_one.addMember(member, owner)
858 True
859 >>> print_distinct_emails()855 >>> print_distinct_emails()
860 From: Team One ...856 From: Team One ...
861 ----------------------------------------857 ----------------------------------------
@@ -881,8 +877,7 @@
881877
882 >>> team_two = factory.makeTeam(878 >>> team_two = factory.makeTeam(
883 ... name='team-two', email='team-two@example.com', owner=owner)879 ... name='team-two', email='team-two@example.com', owner=owner)
884 >>> team_one.addMember(team_two, owner, force_team_add=True)880 >>> ignored = team_one.addMember(team_two, owner, force_team_add=True)
885 True
886 >>> print_distinct_emails()881 >>> print_distinct_emails()
887 From: Team One ...882 From: Team One ...
888 ----------------------------------------883 ----------------------------------------
889884
=== modified file 'lib/lp/registry/doc/teammembership.txt'
--- lib/lp/registry/doc/teammembership.txt 2010-01-05 17:55:30 +0000
+++ lib/lp/registry/doc/teammembership.txt 2010-01-05 17:55:34 +0000
@@ -22,23 +22,28 @@
22 >>> from zope.component import getUtility22 >>> from zope.component import getUtility
23 >>> from canonical.launchpad.interfaces import IPersonSet23 >>> from canonical.launchpad.interfaces import IPersonSet
24 >>> personset = getUtility(IPersonSet)24 >>> personset = getUtility(IPersonSet)
25 >>> foobar = personset.getByName('name16')25 >>> jblack = personset.getByName('jblack')
26 >>> reviewer = foobar26 >>> nopriv = personset.getByName('no-priv')
27 >>> jdub = personset.getByName('jdub')
28 >>> reviewer = nopriv
27 >>> t1 = personset.newTeam(29 >>> t1 = personset.newTeam(
28 ... foobar, 't1', 't1',30 ... jblack, 't1', 't1',
29 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)31 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
30 >>> t2 = personset.newTeam(32 >>> t2 = personset.newTeam(
31 ... foobar, 't2', 't2',33 ... nopriv, 't2', 't2',
32 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)34 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
33 >>> t3 = personset.newTeam(35 >>> t3 = personset.newTeam(
34 ... foobar, 't3', 't3',36 ... jdub, 't3', 't3',
35 ... subscriptionpolicy=TeamSubscriptionPolicy.MODERATED)37 ... subscriptionpolicy=TeamSubscriptionPolicy.MODERATED)
36 >>> t4 = personset.newTeam(38 >>> t4 = personset.newTeam(
37 ... foobar, 't4', 't4',39 ... nopriv, 't4', 't4',
38 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)40 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
39 >>> t5 = personset.newTeam(41 >>> t5 = personset.newTeam(
40 ... foobar, 't5', 't5',42 ... nopriv, 't5', 't5',
41 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)43 ... subscriptionpolicy=TeamSubscriptionPolicy.OPEN)
44 >>> t6 = personset.newTeam(
45 ... jdub, 't6', 't6',
46 ... subscriptionpolicy=TeamSubscriptionPolicy.MODERATED)
4247
43 # Make sure the teams have predictable (and different) creation dates as48 # Make sure the teams have predictable (and different) creation dates as
44 # some of our tests depend on that.49 # some of our tests depend on that.
@@ -66,15 +71,15 @@
66member of that team --somebody has to approve his membership first:71member of that team --somebody has to approve his membership first:
6772
68 >>> [m.displayname for m in t4.allmembers]73 >>> [m.displayname for m in t4.allmembers]
69 [u'Foo Bar', u'Guilherme Salgado']74 [u'Guilherme Salgado', u'No Privileges Person']
7075
71 >>> [m.displayname for m in t3.allmembers]76 >>> [m.displayname for m in t3.allmembers]
72 [u'Foo Bar']77 [u'Jeff Waugh']
73 >>> login_person(t3.teamowner)78 >>> login_person(t3.teamowner)
74 >>> t3.setMembershipData(salgado, TeamMembershipStatus.APPROVED, reviewer)79 >>> t3.setMembershipData(salgado, TeamMembershipStatus.APPROVED, reviewer)
75 >>> flush_database_updates()80 >>> flush_database_updates()
76 >>> [m.displayname for m in t3.allmembers]81 >>> [m.displayname for m in t3.allmembers]
77 [u'Foo Bar', u'Guilherme Salgado']82 [u'Guilherme Salgado', u'Jeff Waugh']
7883
79The join() method is not allowed for teams whose subscription policy is84The join() method is not allowed for teams whose subscription policy is
80RESTRICTED. And it'll be a no-op in case the user has already joined the85RESTRICTED. And it'll be a no-op in case the user has already joined the
@@ -141,12 +146,12 @@
141 # Log in as the team owner.146 # Log in as the team owner.
142 >>> login_person(t3.teamowner)147 >>> login_person(t3.teamowner)
143148
144addMember returns True if the member got added (i.e. he wasn't already a149If the member was added (i.e. he wasn't already a member of the team),
145member of the team).150addMember returns a tuple with True plus the new membership status.
146151
147 >>> t3.addMember(152 >>> t3.addMember(
148 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)153 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)
149 True154 (True, <DBItem TeamMembershipStatus.ADMIN...)
150 >>> from canonical.launchpad.interfaces import ITeamMembershipSet155 >>> from canonical.launchpad.interfaces import ITeamMembershipSet
151 >>> membershipset = getUtility(ITeamMembershipSet)156 >>> membershipset = getUtility(ITeamMembershipSet)
152 >>> flush_database_updates()157 >>> flush_database_updates()
@@ -158,26 +163,26 @@
158 >>> salgado in t3.activemembers163 >>> salgado in t3.activemembers
159 True164 True
160165
161addMember returns True also when the member is added as a proposed166addMember returns (True, PROPOSED) also when the member is added as a
162member.167proposed member.
163168
164 >>> marilize = personset.getByName('marilize')169 >>> marilize = personset.getByName('marilize')
165 >>> t3.addMember(170 >>> t3.addMember(
166 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)171 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)
167 True172 (True, <DBItem TeamMembershipStatus.PROPOSED...)
168 >>> flush_database_updates()173 >>> flush_database_updates()
169 >>> marilize in t3.activemembers174 >>> marilize in t3.activemembers
170 False175 False
171176
172If addMember is called with a person that is already a member, it177If addMember is called with a person that is already a member, it
173returns False.178returns a tuple with False and the current status of the membership.
174179
175 >>> t3.addMember(180 >>> t3.addMember(
176 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)181 ... salgado, reviewer=mark, status=TeamMembershipStatus.ADMIN)
177 False182 (False, <DBItem TeamMembershipStatus.ADMIN...)
178 >>> t3.addMember(183 >>> t3.addMember(
179 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)184 ... marilize, reviewer=mark, status=TeamMembershipStatus.PROPOSED)
180 False185 (False, <DBItem TeamMembershipStatus.PROPOSED...)
181186
182As expected, the membership object implements ITeamMembership.187As expected, the membership object implements ITeamMembership.
183188
@@ -188,29 +193,37 @@
188193
189Note that, by default, the ITeam.addMember() API works slightly different194Note that, by default, the ITeam.addMember() API works slightly different
190when the added member is a team. In that case the team will actually be195when the added member is a team. In that case the team will actually be
191invited to be a member and one of the team's admins will have to accpet the196invited to be a member and one of the team's admins will have to accept the
192invitation before the team is made a member.197invitation before the team is made a member.
193198
194 >>> t1.addMember(t2, reviewer)199 >>> login_person(t1.teamowner)
200
201 # If the reviewer were also an admin of the team being added,
202 # the status would go to APPROVED instead of INVITED.
203 >>> t2.teamowner != t1.teamowner
195 True204 True
205 >>> t1.addMember(t2, reviewer=t1.teamowner)
206 (True, <DBItem TeamMembershipStatus.INVITED...)
196 >>> membership = membershipset.getByPersonAndTeam(t2, t1)207 >>> membership = membershipset.getByPersonAndTeam(t2, t1)
197 >>> membership.status == TeamMembershipStatus.INVITED208 >>> membership.status == TeamMembershipStatus.INVITED
198 True209 True
199 >>> [m.displayname for m in t1.allmembers]210 >>> [m.displayname for m in t1.allmembers]
200 [u'Foo Bar']211 [u'James Blackwell']
201212
202Once one of the t2 admins approve the membership, t2 is shown as a member213Once one of the t2 admins approve the membership, t2 is shown as a member
203of t1.214of t1 and the owner of t2 is an indirect member.
204215
205 >>> login_person(t2.teamowner)216 >>> login_person(t2.teamowner)
206 >>> t2.acceptInvitationToBeMemberOf(t1, comment='something')217 >>> t2.acceptInvitationToBeMemberOf(t1, comment='something')
218 >>> [m.displayname for m in t1.activemembers]
219 [u'James Blackwell', u't2']
207 >>> [m.displayname for m in t1.allmembers]220 >>> [m.displayname for m in t1.allmembers]
208 [u'Foo Bar', u't2']221 [u'James Blackwell', u'No Privileges Person', u't2']
209222
210A team admin can also decline an invitation made to his team.223A team admin can also decline an invitation made to his team.
211224
212 >>> t2.addMember(t3, reviewer=mark)225 >>> t2.addMember(t3, reviewer=mark)
213 True226 (True, <DBItem TeamMembershipStatus.INVITED...)
214 >>> login_person(t3.teamowner)227 >>> login_person(t3.teamowner)
215 >>> t3.declineInvitationToBeMemberOf(t2, comment='something')228 >>> t3.declineInvitationToBeMemberOf(t2, comment='something')
216 >>> membership = membershipset.getByPersonAndTeam(t3, t2)229 >>> membership = membershipset.getByPersonAndTeam(t3, t2)
@@ -222,21 +235,40 @@
222force_team_add=True to addMember(). We'll use that to add t3 as a member of235force_team_add=True to addMember(). We'll use that to add t3 as a member of
223t2, thus making all t3 members be considered members of t2 as well.236t2, thus making all t3 members be considered members of t2 as well.
224237
225 >>> login_person(t3.teamowner)238 >>> login_person(t2.teamowner)
226 >>> t2.addMember(t3, reviewer=mark, force_team_add=True)239
240 # If the reviewer is also an admin of the team being added,
241 # force_team_add is unnecessary, and we can't prove that that
242 # argument works.
243 >>> t3.teamowner != t2.teamowner
227 True244 True
245 >>> t2.addMember(t3, reviewer=t2.teamowner, force_team_add=True)
246 (True, <DBItem TeamMembershipStatus.APPROVED...)
228 >>> [m.displayname for m in t2.allmembers]247 >>> [m.displayname for m in t2.allmembers]
229 [u'Foo Bar', u'Guilherme Salgado', u't3']248 [u'Guilherme Salgado', u'Jeff Waugh', u'No Privileges Person', u't3']
230249
231And members of t1 as well, since t2 is a member of t1.250And members of t1 as well, since t2 is a member of t1.
232251
233 >>> [m.displayname for m in t1.allmembers]252 >>> [m.displayname for m in t1.allmembers]
234 [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']253 [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
254 u'No Privileges Person', u't2', u't3']
255
256
257Passing in force_team_add=True is not necessary if the reviewer is the
258admin of the team being added.
259
260 >>> login_person(t3.teamowner)
261 >>> t6.addMember(t3, reviewer=t3.teamowner)
262 (True, <DBItem TeamMembershipStatus.APPROVED...)
263 >>> [m.displayname for m in t6.allmembers]
264 [u'Guilherme Salgado', u'Jeff Waugh', u't3']
235265
236Can we add t2 as a member of t3? No, we prevent this kind of loop, and users266Can we add t2 as a member of t3? No, we prevent this kind of loop, and users
237can't do this because our vocabularies won't allow members that would cause267can't do this because our vocabularies won't allow members that would cause
238loops.268loops.
239269
270 >>> foobar = personset.getByEmail('foo.bar@canonical.com')
271 >>> login_person(foobar)
240 >>> t3.addMember(t2, reviewer)272 >>> t3.addMember(t2, reviewer)
241 Traceback (most recent call last):273 Traceback (most recent call last):
242 ...274 ...
@@ -246,19 +278,21 @@
246Adding t2 as a member of t5 will add all t2 members as t5 members too.278Adding t2 as a member of t5 will add all t2 members as t5 members too.
247279
248 >>> t5.addMember(t2, reviewer, force_team_add=True)280 >>> t5.addMember(t2, reviewer, force_team_add=True)
249 True281 (True, <DBItem TeamMembershipStatus.APPROVED...)
250 >>> [m.displayname for m in t5.allmembers]282 >>> [m.displayname for m in t5.allmembers]
251 [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']283 [u'Guilherme Salgado', u'Jeff Waugh', u'No Privileges Person',
284 u't2', u't3']
252285
253Adding t5 and t1 as members of t4 will add all t5 and t1 members as t4286Adding t5 and t1 as members of t4 will add all t5 and t1 members as t4
254members too.287members too.
255288
256 >>> t4.addMember(t5, reviewer, force_team_add=True)289 >>> t4.addMember(t5, reviewer, force_team_add=True)
257 True290 (True, <DBItem TeamMembershipStatus.APPROVED...)
258 >>> t4.addMember(t1, reviewer, force_team_add=True)291 >>> t4.addMember(t1, reviewer, force_team_add=True)
259 True292 (True, <DBItem TeamMembershipStatus.APPROVED...)
260 >>> [m.displayname for m in t4.allmembers]293 >>> [m.displayname for m in t4.allmembers]
261 [u'Foo Bar', u'Guilherme Salgado', u't1', u't2', u't3', u't5']294 [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
295 u'No Privileges Person', u't1', u't2', u't3', u't5']
262296
263 >>> flush_database_updates()297 >>> flush_database_updates()
264298
@@ -305,18 +339,20 @@
305member anymore, it doesn't have any members apart from its owner.339member anymore, it doesn't have any members apart from its owner.
306340
307 >>> [m.displayname for m in t5.allmembers]341 >>> [m.displayname for m in t5.allmembers]
308 [u'Foo Bar']342 [u'No Privileges Person']
309343
310Removing t2 from t5 won't remove it from t4, because t2 is also a member of344Removing t2 from t5 won't remove it from t4, because t2 is also a member of
311t1, which is a member of t4.345t1, which is a member of t4.
312346
313 >>> [m.displayname for m in t4.allmembers]347 >>> [m.displayname for m in t4.allmembers]
314 [u'Foo Bar', u'Guilherme Salgado', u't1', u't2', u't3', u't5']348 [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
349 u'No Privileges Person', u't1', u't2', u't3', u't5']
315350
316Nothing changes in t1, because t5 wasn't one of its members.351Nothing changes in t1, because t5 wasn't one of its members.
317352
318 >>> [m.displayname for m in t1.allmembers]353 >>> [m.displayname for m in t1.allmembers]
319 [u'Foo Bar', u'Guilherme Salgado', u't2', u't3']354 [u'Guilherme Salgado', u'James Blackwell', u'Jeff Waugh',
355 u'No Privileges Person', u't2', u't3']
320356
321If 'Guilherme Salgado' decides to leave t3, he'll also be removed from t1357If 'Guilherme Salgado' decides to leave t3, he'll also be removed from t1
322and t2, but not from t4, because he's a direct member of t4.358and t2, but not from t4, because he's a direct member of t4.
@@ -350,31 +386,31 @@
350386
351 >>> cprov = getUtility(IPersonSet).getByName('cprov')387 >>> cprov = getUtility(IPersonSet).getByName('cprov')
352 >>> t3.addMember(cprov, reviewer)388 >>> t3.addMember(cprov, reviewer)
353 True389 (True, <DBItem TeamMembershipStatus.APPROVED...)
354 >>> [m.displayname for m in t3.allmembers]390 >>> [m.displayname for m in t3.allmembers]
355 [u'Celso Providelo', u'Foo Bar']391 [...u'Celso Providelo'...
356392
357 >>> [m.displayname for m in t2.allmembers]393 >>> [m.displayname for m in t2.allmembers]
358 [u'Celso Providelo', u'Foo Bar', u't3']394 [...u'Celso Providelo'...
359395
360 >>> [m.displayname for m in t1.allmembers]396 >>> [m.displayname for m in t1.allmembers]
361 [u'Celso Providelo', u'Foo Bar', u't2', u't3']397 [...u'Celso Providelo'...
362398
363 >>> [m.displayname for m in t4.allmembers]399 >>> [m.displayname for m in t4.allmembers]
364 [u'Celso Providelo', u'Foo Bar', u'Guilherme Salgado', u't1', u't2',400 [...u'Celso Providelo'...
365 u't3', u't5']401
366402
367403It's important to note that even if the owner leaves the team, which
368It's important to note that even if Foo Bar leaves the team he's the owner,404removes his membership, he will still be the team's owner and retain his
369he'll retains his rights over the team because he's the team's owner. This405rights over it. This ensures we'll never have teams which can't be
370ensures we'll never have teams which can't be managed.406managed.
371407
372 >>> login_person(foobar)408 >>> login_person(t5.teamowner)
373 >>> foobar.leave(t5)409 >>> t5.teamowner.leave(t5)
374 >>> flush_database_updates()410 >>> flush_database_updates()
375 >>> [m.displayname for m in t5.allmembers]411 >>> [m.displayname for m in t5.allmembers]
376 []412 []
377 >>> foobar.inTeam(t5)413 >>> t5.teamowner.inTeam(t5)
378 True414 True
379415
380416
@@ -390,7 +426,7 @@
390426
391 # Foo Bar is a launchpad admin, but even so he can't change a membership's427 # Foo Bar is a launchpad admin, but even so he can't change a membership's
392 # status/expiry-date by hand.428 # status/expiry-date by hand.
393 >>> login('foo.bar@canonical.com')429 >>> login_person(foobar)
394 >>> membership = foobar.myactivememberships[0]430 >>> membership = foobar.myactivememberships[0]
395 >>> membership.status = None431 >>> membership.status = None
396 Traceback (most recent call last):432 Traceback (most recent call last):
@@ -709,7 +745,7 @@
709745
710 >>> [(membership.person.name, membership.status.title)746 >>> [(membership.person.name, membership.status.title)
711 ... for membership in t3.member_memberships]747 ... for membership in t3.member_memberships]
712 [(u'cprov', 'Approved'), (u'name16', 'Administrator')]748 [(u'cprov', 'Approved'), (u'jdub', 'Administrator')]
713749
714A team has a number of other methods that return the people which are members750A team has a number of other methods that return the people which are members
715of it, all based on Person.getMembersByStatus:751of it, all based on Person.getMembersByStatus:
@@ -748,7 +784,7 @@
748admin members plus the owner in case he is not one of the admin members.784admin members plus the owner in case he is not one of the admin members.
749785
750 >>> [admin.unique_displayname for admin in t3.adminmembers]786 >>> [admin.unique_displayname for admin in t3.adminmembers]
751 [u'Foo Bar (name16)']787 [u'Jeff Waugh (jdub)']
752 >>> list(t3.getDirectAdministrators()) == list(t3.adminmembers)788 >>> list(t3.getDirectAdministrators()) == list(t3.adminmembers)
753 True789 True
754790
@@ -823,7 +859,7 @@
823 >>> admins = getUtility(IPersonSet).getByName('admins')859 >>> admins = getUtility(IPersonSet).getByName('admins')
824 >>> login_person(t1.teamowner)860 >>> login_person(t1.teamowner)
825 >>> t1.addMember(admins, reviewer=t1.teamowner, force_team_add=True)861 >>> t1.addMember(admins, reviewer=t1.teamowner, force_team_add=True)
826 True862 (True, <DBItem TeamMembershipStatus.APPROVED...)
827 >>> flush_database_updates()863 >>> flush_database_updates()
828 >>> print '\n'.join(sorted(864 >>> print '\n'.join(sorted(
829 ... team.name for team in salgado.teams_participated_in))865 ... team.name for team in salgado.teams_participated_in))
@@ -834,11 +870,12 @@
834 t1870 t1
835 t4871 t4
836872
837On the other hand, making t2 a member of admins won't change anything873On the other hand, making t3 a member of admins won't change anything
838for Salgado.874for Salgado.
839875
840 >>> admins.addMember(t2, reviewer=admins.teamowner, force_team_add=True)876 >>> login_person(foobar)
841 True877 >>> admins.addMember(t3, reviewer=admins.teamowner, force_team_add=True)
878 (True, <DBItem TeamMembershipStatus.APPROVED...)
842 >>> flush_database_updates()879 >>> flush_database_updates()
843 >>> print '\n'.join(sorted(880 >>> print '\n'.join(sorted(
844 ... team.name for team in salgado.teams_participated_in))881 ... team.name for team in salgado.teams_participated_in))
@@ -855,8 +892,8 @@
855Person instances have membership caches (_inTeam_cache) to avoid the892Person instances have membership caches (_inTeam_cache) to avoid the
856need to reissue identical membership queries repeatedly. (This test uses893need to reissue identical membership queries repeatedly. (This test uses
857Person directly to allow us access to an unproxied object, since894Person directly to allow us access to an unproxied object, since
858_inTeam_cache is private, and TeamMembershipSet directly to allow us to895_inTeam_cache is private, and it uses TeamMembershipSet directly to allow
859call TeamMembership.setStatus, which is private).896us to call TeamMembership.setStatus, which is private).
860897
861 >>> from lp.registry.model.person import Person898 >>> from lp.registry.model.person import Person
862 >>> from lp.registry.model.teammembership import TeamMembershipSet899 >>> from lp.registry.model.teammembership import TeamMembershipSet
@@ -864,7 +901,7 @@
864 >>> no_priv.inTeam(admins)901 >>> no_priv.inTeam(admins)
865 False902 False
866 >>> no_priv._inTeam_cache903 >>> no_priv._inTeam_cache
867 {25: False}904 {...25: False...}
868905
869This cache is cleared when memberships are created:906This cache is cleared when memberships are created:
870907
@@ -920,7 +957,7 @@
920 >>> transaction.commit()957 >>> transaction.commit()
921958
922 >>> [m.displayname for m in t3.allmembers]959 >>> [m.displayname for m in t3.allmembers]
923 [u'Bad-user', u'Foo Bar']960 [u'Bad-user', u'Jeff Waugh']
924 >>> bad_user.is_valid_person961 >>> bad_user.is_valid_person
925 False962 False
926 >>> print bad_user.preferredemail963 >>> print bad_user.preferredemail
927964
=== modified file 'lib/lp/registry/doc/vocabularies.txt'
--- lib/lp/registry/doc/vocabularies.txt 2009-12-07 16:07:43 +0000
+++ lib/lp/registry/doc/vocabularies.txt 2010-01-05 17:55:34 +0000
@@ -255,8 +255,7 @@
255255
256 >>> from canonical.launchpad.interfaces import PersonVisibility256 >>> from canonical.launchpad.interfaces import PersonVisibility
257 >>> otherteam = person_set.getByName('otherteam')257 >>> otherteam = person_set.getByName('otherteam')
258 >>> otherteam.addMember(foo_bar, foo_bar)258 >>> ignored = otherteam.addMember(foo_bar, foo_bar)
259
260 >>> otherteam.visibility = PersonVisibility.PRIVATE_MEMBERSHIP259 >>> otherteam.visibility = PersonVisibility.PRIVATE_MEMBERSHIP
261 >>> for term in person_active_membership:260 >>> for term in person_active_membership:
262 ... print term.token, term.value.displayname, term.title261 ... print term.token, term.value.displayname, term.title
@@ -1398,7 +1397,7 @@
1398 >>> registry_member = factory.makePerson()1397 >>> registry_member = factory.makePerson()
1399 >>> celebs = getUtility(ILaunchpadCelebrities)1398 >>> celebs = getUtility(ILaunchpadCelebrities)
1400 >>> registry = celebs.registry_experts1399 >>> registry = celebs.registry_experts
1401 >>> registry.addMember(registry_member, registry.teamowner)1400 >>> ignored = registry.addMember(registry_member, registry.teamowner)
1402 >>> logout()1401 >>> logout()
14031402
1404 >>> login_person(registry_member)1403 >>> login_person(registry_member)
14051404
=== modified file 'lib/lp/registry/stories/mailinglists/lifecycle.txt'
--- lib/lp/registry/stories/mailinglists/lifecycle.txt 2009-12-03 21:19:49 +0000
+++ lib/lp/registry/stories/mailinglists/lifecycle.txt 2010-01-05 17:55:34 +0000
@@ -363,7 +363,7 @@
363 >>> person_set = getUtility(IPersonSet)363 >>> person_set = getUtility(IPersonSet)
364 >>> test = person_set.getByName('name12')364 >>> test = person_set.getByName('name12')
365 >>> experts = getUtility(ILaunchpadCelebrities).mailing_list_experts365 >>> experts = getUtility(ILaunchpadCelebrities).mailing_list_experts
366 >>> experts.addMember(test, reviewer=experts.teamowner)366 >>> ignored = experts.addMember(test, reviewer=experts.teamowner)
367 >>> logout()367 >>> logout()
368 >>> transaction.commit()368 >>> transaction.commit()
369369
370370
=== modified file 'lib/lp/registry/stories/mailinglists/subscriptions.txt'
--- lib/lp/registry/stories/mailinglists/subscriptions.txt 2009-12-03 20:28:54 +0000
+++ lib/lp/registry/stories/mailinglists/subscriptions.txt 2010-01-05 17:55:34 +0000
@@ -195,7 +195,7 @@
195 >>> person_set = getUtility(IPersonSet)195 >>> person_set = getUtility(IPersonSet)
196 >>> jdub = person_set.getByName('jdub')196 >>> jdub = person_set.getByName('jdub')
197 >>> mark = person_set.getByName('mark')197 >>> mark = person_set.getByName('mark')
198 >>> beta.addMember(jdub, reviewer=mark)198 >>> ignored = beta.addMember(jdub, reviewer=mark)
199 >>> from canonical.database.sqlbase import flush_database_updates199 >>> from canonical.database.sqlbase import flush_database_updates
200 >>> flush_database_updates()200 >>> flush_database_updates()
201 >>> logout()201 >>> logout()
@@ -424,9 +424,9 @@
424 >>> salgado = person_set.getByName('salgado')424 >>> salgado = person_set.getByName('salgado')
425 >>> jordi = person_set.getByName('jordi')425 >>> jordi = person_set.getByName('jordi')
426 >>> rosetta_admins = person_set.getByName('rosetta-admins')426 >>> rosetta_admins = person_set.getByName('rosetta-admins')
427 >>> rosetta_admins.addMember(salgado, reviewer=mark)427 >>> ignored = rosetta_admins.addMember(salgado, reviewer=mark)
428 >>> rosetta_admins.mailing_list.subscribe(salgado)428 >>> rosetta_admins.mailing_list.subscribe(salgado)
429 >>> rosetta_admins.addMember(jordi, reviewer=mark)429 >>> ignored = rosetta_admins.addMember(jordi, reviewer=mark)
430 >>> rosetta_admins.mailing_list.subscribe(jordi)430 >>> rosetta_admins.mailing_list.subscribe(jordi)
431 >>> logout()431 >>> logout()
432 >>> browser.reload()432 >>> browser.reload()
433433
=== modified file 'lib/lp/registry/stories/person/xx-admin-person-review.txt'
--- lib/lp/registry/stories/person/xx-admin-person-review.txt 2010-01-04 10:24:29 +0000
+++ lib/lp/registry/stories/person/xx-admin-person-review.txt 2010-01-05 17:55:34 +0000
@@ -103,7 +103,8 @@
103 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities103 >>> from canonical.launchpad.interfaces import ILaunchpadCelebrities
104 >>> from zope.component import getUtility104 >>> from zope.component import getUtility
105 >>> registry_team = getUtility(ILaunchpadCelebrities).registry_experts105 >>> registry_team = getUtility(ILaunchpadCelebrities).registry_experts
106 >>> registry_team.addMember(registry_expert, registry_team.teamowner)106 >>> ignored = registry_team.addMember(
107 ... registry_expert, registry_team.teamowner)
107 >>> print registry_expert.inTeam(registry_team)108 >>> print registry_expert.inTeam(registry_team)
108 True109 True
109 >>> logout()110 >>> logout()
110111
=== modified file 'lib/lp/registry/stories/product/xx-product-edit.txt'
--- lib/lp/registry/stories/product/xx-product-edit.txt 2009-10-08 16:29:45 +0000
+++ lib/lp/registry/stories/product/xx-product-edit.txt 2010-01-05 17:55:34 +0000
@@ -292,7 +292,7 @@
292 ... name='reggie', email='reggie@example.com', password='test')292 ... name='reggie', email='reggie@example.com', password='test')
293 >>> celebs = getUtility(ILaunchpadCelebrities)293 >>> celebs = getUtility(ILaunchpadCelebrities)
294 >>> registry = celebs.registry_experts294 >>> registry = celebs.registry_experts
295 >>> registry.addMember(registry_member, registry.teamowner)295 >>> ignored = registry.addMember(registry_member, registry.teamowner)
296 >>> logout()296 >>> logout()
297297
298 >>> registry_browser = setupBrowser(298 >>> registry_browser = setupBrowser(
299299
=== modified file 'lib/lp/registry/stories/product/xx-productset.txt'
--- lib/lp/registry/stories/product/xx-productset.txt 2009-09-18 17:38:50 +0000
+++ lib/lp/registry/stories/product/xx-productset.txt 2010-01-05 17:55:34 +0000
@@ -23,7 +23,7 @@
23 ... name='reggie', email='reggie@example.com', password='test')23 ... name='reggie', email='reggie@example.com', password='test')
24 >>> celebs = getUtility(ILaunchpadCelebrities)24 >>> celebs = getUtility(ILaunchpadCelebrities)
25 >>> registry = celebs.registry_experts25 >>> registry = celebs.registry_experts
26 >>> registry.addMember(registry_member, registry.teamowner)26 >>> ignored = registry.addMember(registry_member, registry.teamowner)
27 >>> logout()27 >>> logout()
2828
29 >>> registry_browser = setupBrowser(29 >>> registry_browser = setupBrowser(
3030
=== modified file 'lib/lp/registry/stories/team/xx-team-add-my-teams.txt'
--- lib/lp/registry/stories/team/xx-team-add-my-teams.txt 2009-11-22 15:43:16 +0000
+++ lib/lp/registry/stories/team/xx-team-add-my-teams.txt 2010-01-05 17:55:34 +0000
@@ -6,8 +6,9 @@
6This is done from the +add-my-teams page, which is linked from a team's6This is done from the +add-my-teams page, which is linked from a team's
7home page.7home page.
88
9 >>> browser = setupBrowser(auth='Basic salgado@ubuntu.com:zeca')9 >>> browser = setupBrowser(
10 >>> browser.open('http://launchpad.dev/~ubuntu-team')10 ... auth='Basic colin.watson@ubuntulinux.com:test')
11 >>> browser.open('http://launchpad.dev/~name21')
11 >>> browser.getLink('Add one of my teams').click()12 >>> browser.getLink('Add one of my teams').click()
12 >>> browser.title13 >>> browser.title
13 'Propose/add one of your teams to another one...14 'Propose/add one of your teams to another one...
@@ -18,47 +19,48 @@
18 >>> print extract_text(find_tag_by_id(browser.contents, 'candidates'))19 >>> print extract_text(find_tag_by_id(browser.contents, 'candidates'))
19 This is a moderated team, so one of its administrators will have20 This is a moderated team, so one of its administrators will have
20 to review any memberships you propose.21 to review any memberships you propose.
21 Launchpad Administrators22 GuadaMen
22 Mailing List Experts23 Ubuntu Security Team
23 Rosetta Administrators24 Ubuntu Team
24 or Cancel25 or Cancel
2526
26We'll now propose Launchpad Administrators as a member of Ubuntu Team.27We'll now propose Ubuntu Team as a member of the Hoary Gnome Team (name21).
2728
28 >>> browser.getControl(name='field.teams').value = ['admins']29 >>> browser.open('http://launchpad.dev/~name21')
30 >>> link = browser.getLink('Add one of my teams')
31 >>> link.click()
32 >>> browser.getControl(name='field.teams').value = ['ubuntu-team']
29 >>> browser.getControl('Continue').click()33 >>> browser.getControl('Continue').click()
30 >>> browser.title34 >>> browser.title
31 'Ubuntu Team in Launchpad'35 'Hoary Gnome Team in Launchpad'
32 >>> print get_feedback_messages(browser.contents)36 >>> print get_feedback_messages(browser.contents)
33 [u'Launchpad Administrators has been proposed to this team.']37 [u'Ubuntu Team has been proposed to this team.']
34 >>> print extract_text(38 >>> print extract_text(
35 ... find_tag_by_id(browser.contents, 'recently-applied'))39 ... find_tag_by_id(browser.contents, 'recently-proposed'))
36 Pending approval40 Pending approval
37 Launchpad Administrators41 Ubuntu Team...
38 ...
3942
40If it were an OPEN team, we'd be able to directly add any of our teams as43If it were an OPEN team, we'd be able to directly add any of our teams as
41members.44members.
4245
43 >>> admin_browser.open('http://launchpad.dev/~ubuntu-team/+edit')46 >>> admin_browser.open('http://launchpad.dev/~name21/+edit')
44 >>> admin_browser.getControl(47 >>> admin_browser.getControl(
45 ... name='field.subscriptionpolicy').displayValue = ['Open Team']48 ... name='field.subscriptionpolicy').displayValue = ['Open Team']
46 >>> admin_browser.getControl('Save').click()49 >>> admin_browser.getControl('Save').click()
47 >>> admin_browser.title50 >>> admin_browser.title
48 'Ubuntu Team in Launchpad'51 'Hoary Gnome Team in Launchpad'
4952
50 >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')53 >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
51 >>> browser.getControl(name='field.teams').value = ['rosetta-admins']54 >>> browser.getControl(name='field.teams').value = ['ubuntu-team']
52 >>> browser.getControl('Continue').click()55 >>> browser.getControl('Continue').click()
53 >>> browser.title56 >>> browser.title
54 'Ubuntu Team in Launchpad'57 'Hoary Gnome Team in Launchpad'
55 >>> print get_feedback_messages(browser.contents)58 >>> print get_feedback_messages(browser.contents)
56 [u'Rosetta Administrators has been added to this team.']59 [u'Ubuntu Team has been added to this team.']
57 >>> print extract_text(60 >>> print extract_text(
58 ... find_tag_by_id(browser.contents, 'recently-approved'))61 ... find_tag_by_id(browser.contents, 'recently-approved'))
59 Recently approved62 Latest members
60 Rosetta Administrators63 Ubuntu Team...
61 ...
6264
63In the case of restricted teams, though, there is no way to propose any of65In the case of restricted teams, though, there is no way to propose any of
64your teams as members.66your teams as members.
@@ -88,38 +90,38 @@
88 Traceback (most recent call last):90 Traceback (most recent call last):
89 Unauthorized:...91 Unauthorized:...
9092
91You also can't propose a team to itself. Here although Salgado is usually93You also can't propose a team to itself. Here although Colin Watson is
92allowed to propose Launchpad Administrators in other team, it doesn't94usually allowed to propose Guadamen in other team, it doesn't appear in
93appear in the list when proposing a team for the Launchpad95the list when proposing a team for the Guadamen team. Likewise Mailing
94Administrators team. Likewise Mailing List Experts isn't shown because96List Experts isn't shown because the Launchpad Administrators are a
95the Launchpad Administrators are a member of Mailing List Experts.97member of Mailing List Experts. Adding Mailing List Experts would
96Adding Mailing List Experts would create a cycle.98create a cycle.
9799
98 >>> browser.open('http://launchpad.dev/~admins/+add-my-teams')100 >>> browser.open('http://launchpad.dev/~guadamen/+add-my-teams')
99 >>> browser.getControl(name='field.teams').options101 >>> browser.getControl(name='field.teams').options
100 ['rosetta-admins']102 ['ubuntu-security']
101103
102Teams that are already member of the team can't be proposed or added.104Teams that are already member of the team can't be proposed or added.
103For example, Rosetta Administrators is not in the list of choices105For example, Ubuntu Team is not in the list of choices
104anymore of the Ubuntu Team:106anymore of the Hoary Gnome Team:
105107
106 >>> admin_browser.open('http://launchpad.dev/~ubuntu-team/+edit')108 >>> admin_browser.open('http://launchpad.dev/~name21/+edit')
107 >>> admin_browser.getControl(109 >>> admin_browser.getControl(
108 ... name='field.subscriptionpolicy').displayValue = ['Open']110 ... name='field.subscriptionpolicy').displayValue = ['Open']
109 >>> admin_browser.getControl('Save').click()111 >>> admin_browser.getControl('Save').click()
110112
111 >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')113 >>> browser.open('http://launchpad.dev/~name21/+members')
114 >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
112 >>> browser.getControl(name='field.teams').options115 >>> browser.getControl(name='field.teams').options
113 ['admins', 'mailing-list-experts']116 ['guadamen', 'ubuntu-security']
114 >>> browser.getControl(name='field.teams').value = [117 >>> browser.getControl(name='field.teams').value = [
115 ... 'admins', 'mailing-list-experts']118 ... 'guadamen', 'ubuntu-security']
116 >>> browser.getControl('Continue').click()119 >>> browser.getControl('Continue').click()
117 >>> print "\n".join(get_feedback_messages(browser.contents))120 >>> print "\n".join(get_feedback_messages(browser.contents))
118 Launchpad Administrators, Mailing List Experts have been added to this121 GuadaMen, Ubuntu Security Team have been added to this team.
119 team.
120122
121And when no teams can be added, a message is displayed:123And when no teams can be added, a message is displayed:
122124
123 >>> browser.open('http://launchpad.dev/~ubuntu-team/+add-my-teams')125 >>> browser.open('http://launchpad.dev/~name21/+add-my-teams')
124 >>> print extract_text(find_tag_by_id(browser.contents, 'no-candidates'))126 >>> print extract_text(find_tag_by_id(browser.contents, 'no-candidates'))
125 None of the teams you administer can be added to this team.127 None of the teams you administer can be added to this team.
126128
=== modified file 'lib/lp/registry/stories/teammembership/20-managing-members.txt'
--- lib/lp/registry/stories/teammembership/20-managing-members.txt 2009-09-18 21:24:09 +0000
+++ lib/lp/registry/stories/teammembership/20-managing-members.txt 2010-01-05 17:55:34 +0000
@@ -28,7 +28,15 @@
28 >>> print_members(browser.contents, 'proposedmembers')28 >>> print_members(browser.contents, 'proposedmembers')
29 Foo Bar29 Foo Bar
3030
31 >>> print_members(browser.contents, 'inactivemembers')31Former members are only viewable by admins of the team.
32
33 >>> print find_tag_by_id(browser.contents, 'inactivemembers')
34 None
35
36 >>> name12_browser = setupBrowser(
37 ... auth="Basic test@canonical.com:test")
38 >>> name12_browser.open(browser.url)
39 >>> print_members(name12_browser.contents, 'inactivemembers')
32 Karl Tilbury40 Karl Tilbury
33 No Privileges Person41 No Privileges Person
3442
@@ -57,12 +65,13 @@
57 ... [launchpad]65 ... [launchpad]
58 ... default_batch_size: 266 ... default_batch_size: 2
59 ... """)67 ... """)
60 >>> browser.open('http://launchpad.dev/~admins/+members?inactive_batch=2')68 >>> admin_browser.open(
61 >>> print_members(browser.contents, 'inactivemembers')69 ... 'http://launchpad.dev/~admins/+members?inactive_batch=2')
70 >>> print_members(admin_browser.contents, 'inactivemembers')
62 Celso Providelo71 Celso Providelo
63 David Allouche72 David Allouche
64 >>> browser.getLink('Next', index=2).click()73 >>> admin_browser.getLink('Next', index=2).click()
65 >>> print_members(browser.contents, 'inactivemembers')74 >>> print_members(admin_browser.contents, 'inactivemembers')
66 James Blackwell75 James Blackwell
67 >>> config_data = config.pop('default-batch-size')76 >>> config_data = config.pop('default-batch-size')
6877
6978
=== modified file 'lib/lp/registry/stories/teammembership/private-team.txt'
--- lib/lp/registry/stories/teammembership/private-team.txt 2009-10-26 21:12:49 +0000
+++ lib/lp/registry/stories/teammembership/private-team.txt 2010-01-05 17:55:34 +0000
@@ -17,7 +17,7 @@
17 >>> person_set = getUtility(IPersonSet)17 >>> person_set = getUtility(IPersonSet)
18 >>> cprov = person_set.getByName('cprov')18 >>> cprov = person_set.getByName('cprov')
19 >>> login_person(owner)19 >>> login_person(owner)
20 >>> priv_team.addMember(cprov, reviewer=owner)20 >>> ignored = priv_team.addMember(cprov, reviewer=owner)
21 >>> logout()21 >>> logout()
2222
23 >>> admin_browser.open('http://launchpad.dev/~private-team')23 >>> admin_browser.open('http://launchpad.dev/~private-team')
2424
=== modified file 'lib/lp/registry/stories/teammembership/xx-add-member.txt'
--- lib/lp/registry/stories/teammembership/xx-add-member.txt 2009-10-26 14:37:31 +0000
+++ lib/lp/registry/stories/teammembership/xx-add-member.txt 2010-01-05 17:55:34 +0000
@@ -49,7 +49,7 @@
49 >>> from canonical.launchpad.interfaces import TeamMembershipStatus49 >>> from canonical.launchpad.interfaces import TeamMembershipStatus
50 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout50 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
51 >>> login(ANONYMOUS) # login() because we need a zope interaction.51 >>> login(ANONYMOUS) # login() because we need a zope interaction.
52 >>> cprov_landscape_membership.setStatus(52 >>> ignored = cprov_landscape_membership.setStatus(
53 ... TeamMembershipStatus.DEACTIVATED, landscape_team.teamowner)53 ... TeamMembershipStatus.DEACTIVATED, landscape_team.teamowner)
54 >>> logout()54 >>> logout()
55 >>> cprov_landscape_membership.syncUpdate()55 >>> cprov_landscape_membership.syncUpdate()
@@ -171,44 +171,47 @@
171same. When an admin accepts or declines an invitation, the other admin can't171same. When an admin accepts or declines an invitation, the other admin can't
172take action on that invitation anymore.172take action on that invitation anymore.
173173
174First invite ubuntu-team to be member of the name21 team.174First invite name20 to be a member of ubuntu-team.
175175
176 >>> browser.open('http://launchpad.dev/~name21/+addmember')176 >>> browser = setupBrowser(
177 >>> browser.getControl('New member:').value = 'ubuntu-team'177 ... auth='Basic colin.watson@ubuntulinux.com:test')
178 >>> browser.open('http://launchpad.dev/~ubuntu-team/+addmember')
179 >>> browser.getControl('New member:').value = 'name20'
178 >>> browser.getControl('Add Member').click()180 >>> browser.getControl('Add Member').click()
179181
180 >>> for tag in find_tags_by_class(browser.contents,182 >>> for tag in find_tags_by_class(browser.contents,
181 ... 'informational message'):183 ... 'informational message'):
182 ... print tag.renderContents()184 ... print tag.renderContents()
183 Ubuntu Team (ubuntu-team) has been invited to join this team.185 Warty Security Team (name20) has been invited to join this team.
184186
185Open the invitations page with one admin browser.187Open the invitations page with one admin browser.
186188
187 >>> browser.open('http://launchpad.dev/~ubuntu-team/+invitation/name21')189 >>> browser = setupBrowser(auth='Basic mark@example.com:test')
190 >>> browser.open('http://launchpad.dev/~name20/+invitation/ubuntu-team')
188191
189Open the same page with another admin browser.192Open the same page with another admin browser.
190193
191 >>> second_browser = setupBrowser(auth='Basic foo.bar@canonical.com:test')194 >>> second_browser = setupBrowser(auth='Basic mark@example.com:test')
192 >>> second_browser.open(195 >>> second_browser.open(
193 ... 'http://launchpad.dev/~ubuntu-team/+invitation/name21')196 ... 'http://launchpad.dev/~name20/+invitation/ubuntu-team')
194197
195Accept the invitation in the first browser.198Accept the invitation in the first browser.
196199
197 >>> browser.getControl('Accept').click()200 >>> browser.getControl('Accept').click()
198 >>> browser.url201 >>> browser.url
199 'http://launchpad.dev/~ubuntu-team'202 'http://launchpad.dev/~name20'
200203
201 >>> for tag in find_tags_by_class(browser.contents,204 >>> for tag in find_tags_by_class(browser.contents,
202 ... 'informational message'):205 ... 'informational message'):
203 ... print tag.renderContents()206 ... print tag.renderContents()
204 This team is now a member of Hoary Gnome Team207 This team is now a member of Ubuntu Team
205208
206Accepting the invitation in the second browser, redirects to the team page209Accepting the invitation in the second browser, redirects to the team page
207and a message is displayed.210and a message is displayed.
208211
209 >>> second_browser.getControl('Accept').click()212 >>> second_browser.getControl('Accept').click()
210 >>> second_browser.url213 >>> second_browser.url
211 'http://launchpad.dev/~ubuntu-team'214 'http://launchpad.dev/~name20'
212215
213 >>> for tag in find_tags_by_class(second_browser.contents,216 >>> for tag in find_tags_by_class(second_browser.contents,
214 ... 'informational message'):217 ... 'informational message'):
@@ -233,7 +236,7 @@
233 >>> login(ANONYMOUS) # login() because we need a zope interaction.236 >>> login(ANONYMOUS) # login() because we need a zope interaction.
234 >>> carlos_translators_membership = TeamMembership.selectOneBy(237 >>> carlos_translators_membership = TeamMembership.selectOneBy(
235 ... personID=carlos.id, teamID=ubuntu_translators.id)238 ... personID=carlos.id, teamID=ubuntu_translators.id)
236 >>> carlos_translators_membership.setStatus(239 >>> ignored = carlos_translators_membership.setStatus(
237 ... TeamMembershipStatus.DEACTIVATED, ubuntu_translators.teamowner)240 ... TeamMembershipStatus.DEACTIVATED, ubuntu_translators.teamowner)
238 >>> logout()241 >>> logout()
239 >>> carlos_translators_membership.syncUpdate()242 >>> carlos_translators_membership.syncUpdate()
240243
=== modified file 'lib/lp/registry/stories/teammembership/xx-expire-subscription.txt'
--- lib/lp/registry/stories/teammembership/xx-expire-subscription.txt 2009-08-13 19:03:36 +0000
+++ lib/lp/registry/stories/teammembership/xx-expire-subscription.txt 2010-01-05 17:55:34 +0000
@@ -32,7 +32,7 @@
32 ... personID=sampleperson.id, teamID=team.id)32 ... personID=sampleperson.id, teamID=team.id)
33 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout33 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
34 >>> login(ANONYMOUS) # login() because we need a zope interaction.34 >>> login(ANONYMOUS) # login() because we need a zope interaction.
35 >>> tm.setStatus(TeamMembershipStatus.EXPIRED, team.teamowner)35 >>> ignored = tm.setStatus(TeamMembershipStatus.EXPIRED, team.teamowner)
36 >>> logout()36 >>> logout()
3737
38Persist the change:38Persist the change:
3939
=== modified file 'lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt'
--- lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt 2009-12-10 16:15:21 +0000
+++ lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt 2010-01-05 17:55:34 +0000
@@ -141,7 +141,7 @@
141 >>> login('mark@example.com')141 >>> login('mark@example.com')
142 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')142 >>> mirror_admins = personset.getByName('ubuntu-mirror-admins')
143 >>> landscape_devs = personset.getByName('landscape-developers')143 >>> landscape_devs = personset.getByName('landscape-developers')
144 >>> mirror_admins.addMember(144 >>> ignored = mirror_admins.addMember(
145 ... landscape_devs, mirror_admins.teamowner, force_team_add=True)145 ... landscape_devs, mirror_admins.teamowner, force_team_add=True)
146 >>> membership = getUtility(ITeamMembershipSet).getByPersonAndTeam(146 >>> membership = getUtility(ITeamMembershipSet).getByPersonAndTeam(
147 ... landscape_devs, mirror_admins)147 ... landscape_devs, mirror_admins)
148148
=== modified file 'lib/lp/registry/stories/teammembership/xx-private-membership.txt'
--- lib/lp/registry/stories/teammembership/xx-private-membership.txt 2009-12-01 22:09:05 +0000
+++ lib/lp/registry/stories/teammembership/xx-private-membership.txt 2010-01-05 17:55:34 +0000
@@ -43,7 +43,7 @@
43 <...<a href=".../~member" class="sprite person">Gold Member</a>...43 <...<a href=".../~member" class="sprite person">Gold Member</a>...
4444
4545
46 >>> find_tag_by_id(browser.contents, 'recently-applied')46 >>> find_tag_by_id(browser.contents, 'recently-proposed')
47 <...<a href=".../~no-priv" class="sprite person">No Privileges Person</a>...47 <...<a href=".../~no-priv" class="sprite person">No Privileges Person</a>...
4848
49 >>> print extract_text(49 >>> print extract_text(
@@ -257,9 +257,9 @@
257team's home page, they see the private team show up in the "Subteam of"257team's home page, they see the private team show up in the "Subteam of"
258section.258section.
259259
260 >>> admin_browser.open('http://launchpad.dev/~myteam/+addmember')260 >>> owner_browser.open('http://launchpad.dev/~myteam/+addmember')
261 >>> admin_browser.getControl('New member').value = 'guadamen'261 >>> owner_browser.getControl('New member').value = 'guadamen'
262 >>> admin_browser.getControl('Add Member').click()262 >>> owner_browser.getControl('Add Member').click()
263 >>> admin_browser.open(263 >>> admin_browser.open(
264 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')264 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')
265 >>> admin_browser.getControl('Accept').click()265 >>> admin_browser.getControl('Accept').click()
266266
=== modified file 'lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt'
--- lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt 2009-09-08 15:58:38 +0000
+++ lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt 2010-01-05 17:55:34 +0000
@@ -117,7 +117,8 @@
117 >>> commercial_member = getUtility(IPersonSet).getByEmail(117 >>> commercial_member = getUtility(IPersonSet).getByEmail(
118 ... 'commercial-member@canonical.com')118 ... 'commercial-member@canonical.com')
119 >>> celebs = getUtility(ILaunchpadCelebrities)119 >>> celebs = getUtility(ILaunchpadCelebrities)
120 >>> celebs.registry_experts.addMember(commercial_member, commercial_member)120 >>> ignored = celebs.registry_experts.addMember(
121 ... commercial_member, commercial_member)
121 >>> logout()122 >>> logout()
122123
123 >>> browser.open(124 >>> browser.open(
124125
=== modified file 'lib/lp/registry/stories/webservice/xx-private-membership.txt'
--- lib/lp/registry/stories/webservice/xx-private-membership.txt 2009-10-01 12:30:32 +0000
+++ lib/lp/registry/stories/webservice/xx-private-membership.txt 2010-01-05 17:55:34 +0000
@@ -35,9 +35,10 @@
35Similarly, when a public team is a sub-team of a private team, non-members35Similarly, when a public team is a sub-team of a private team, non-members
36cannot see the private team in the public team's super_team's attribute.36cannot see the private team in the public team's super_team's attribute.
3737
38 >>> admin_browser.open('http://launchpad.dev/~myteam/+addmember')38 >>> owner_browser = setupBrowser(auth="Basic owner@canonical.com:test")
39 >>> admin_browser.getControl('New member').value = 'guadamen'39 >>> owner_browser.open('http://launchpad.dev/~myteam/+addmember')
40 >>> admin_browser.getControl('Add Member').click()40 >>> owner_browser.getControl('New member').value = 'guadamen'
41 >>> owner_browser.getControl('Add Member').click()
41 >>> admin_browser.open(42 >>> admin_browser.open(
42 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')43 ... 'http://launchpad.dev/~guadamen/+invitation/myteam')
43 >>> admin_browser.getControl('Accept').click()44 >>> admin_browser.getControl('Accept').click()
4445
=== modified file 'lib/lp/registry/stories/webservice/xx-source-package.txt'
--- lib/lp/registry/stories/webservice/xx-source-package.txt 2009-12-05 18:37:28 +0000
+++ lib/lp/registry/stories/webservice/xx-source-package.txt 2010-01-05 17:55:34 +0000
@@ -67,7 +67,7 @@
67 >>> login('admin@canonical.com')67 >>> login('admin@canonical.com')
68 >>> person = factory.makePerson()68 >>> person = factory.makePerson()
69 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches69 >>> ubuntu_branches = getUtility(ILaunchpadCelebrities).ubuntu_branches
70 >>> ubuntu_branches.addMember(person, ubuntu_branches.teamowner)70 >>> ignored = ubuntu_branches.addMember(person, ubuntu_branches.teamowner)
71 >>> logout()71 >>> logout()
7272
73Then we set the branch on the evolution hoary package:73Then we set the branch on the evolution hoary package:
7474
=== modified file 'lib/lp/registry/stories/webservice/xx-structuralsubscription.txt'
--- lib/lp/registry/stories/webservice/xx-structuralsubscription.txt 2009-12-05 18:37:28 +0000
+++ lib/lp/registry/stories/webservice/xx-structuralsubscription.txt 2010-01-05 17:55:34 +0000
@@ -8,7 +8,7 @@
8 >>> eric_db = factory.makePerson(name='eric')8 >>> eric_db = factory.makePerson(name='eric')
9 >>> michael_db = factory.makePerson(name='michael')9 >>> michael_db = factory.makePerson(name='michael')
10 >>> pythons_db = factory.makeTeam(name='pythons', owner=michael_db)10 >>> pythons_db = factory.makeTeam(name='pythons', owner=michael_db)
11 >>> pythons_db.addMember(eric_db, michael_db)11 >>> ignored = pythons_db.addMember(eric_db, michael_db)
1212
13 >>> fooix_db = factory.makeProduct(name='fooix', owner=eric_db)13 >>> fooix_db = factory.makeProduct(name='fooix', owner=eric_db)
14 >>> fooix01_db = fooix_db.newSeries(eric_db, '0.1', 'Series 0.1')14 >>> fooix01_db = fooix_db.newSeries(eric_db, '0.1', 'Series 0.1')
1515
=== modified file 'lib/lp/registry/tests/bug-249185.txt'
--- lib/lp/registry/tests/bug-249185.txt 2009-04-17 10:32:16 +0000
+++ lib/lp/registry/tests/bug-249185.txt 2010-01-05 17:55:34 +0000
@@ -9,18 +9,19 @@
99
10 >>> login_person(person)10 >>> login_person(person)
11 >>> dev1 = factory.makePerson()11 >>> dev1 = factory.makePerson()
12 >>> devs.addMember(dev1, person)12 >>> ignored = devs.addMember(dev1, person)
1313
14Beta testers has lp-devs and adjutants as members.14Beta testers has lp-devs and adjutants as members.
1515
16 >>> beta_testers.addMember(devs, person, force_team_add=True)16 >>> ignored = beta_testers.addMember(devs, person, force_team_add=True)
17 >>> beta_testers.addMember(adjutants, person, force_team_add=True)17 >>> ignored = beta_testers.addMember(
18 ... adjutants, person, force_team_add=True)
18 >>> dev1.hasParticipationEntryFor(beta_testers)19 >>> dev1.hasParticipationEntryFor(beta_testers)
19 True20 True
2021
21Adjutants has lp-devs as member.22Adjutants has lp-devs as member.
2223
23 >>> adjutants.addMember(devs, person, force_team_add=True)24 >>> ignored = adjutants.addMember(devs, person, force_team_add=True)
24 >>> dev1.hasParticipationEntryFor(adjutants)25 >>> dev1.hasParticipationEntryFor(adjutants)
25 True26 True
2627
2728
=== modified file 'lib/lp/registry/tests/test_teammembership.py'
--- lib/lp/registry/tests/test_teammembership.py 2009-10-19 16:14:18 +0000
+++ lib/lp/registry/tests/test_teammembership.py 2010-01-05 17:55:34 +0000
@@ -546,8 +546,8 @@
546 # Invite team2 as member of team1 and team1 as member of team2. This546 # Invite team2 as member of team1 and team1 as member of team2. This
547 # is not a problem because that won't make any team an active member547 # is not a problem because that won't make any team an active member
548 # of the other.548 # of the other.
549 self.team1.addMember(self.team2, self.foobar)549 self.team1.addMember(self.team2, self.no_priv)
550 self.team2.addMember(self.team1, self.foobar)550 self.team2.addMember(self.team1, self.no_priv)
551 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(551 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
552 self.team1, self.team2)552 self.team1, self.team2)
553 team2_on_team1 = getUtility(ITeamMembershipSet).getByPersonAndTeam(553 team2_on_team1 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
@@ -580,7 +580,7 @@
580 """No status change can create cyclical participation."""580 """No status change can create cyclical participation."""
581 # Invite team1 as a member of team3 and forcibly add team2 as member581 # Invite team1 as a member of team3 and forcibly add team2 as member
582 # of team1 and team3 as member of team2.582 # of team1 and team3 as member of team2.
583 self.team3.addMember(self.team1, self.foobar)583 self.team3.addMember(self.team1, self.no_priv)
584 self.team1.addMember(self.team2, self.foobar, force_team_add=True)584 self.team1.addMember(self.team2, self.foobar, force_team_add=True)
585 self.team2.addMember(self.team3, self.foobar, force_team_add=True)585 self.team2.addMember(self.team3, self.foobar, force_team_add=True)
586586
@@ -593,7 +593,7 @@
593 TeamMembershipStatus.APPROVED, self.foobar)593 TeamMembershipStatus.APPROVED, self.foobar)
594594
595 def test_invited_member_can_be_made_admin(self):595 def test_invited_member_can_be_made_admin(self):
596 self.team2.addMember(self.team1, self.foobar)596 self.team2.addMember(self.team1, self.no_priv)
597 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(597 team1_on_team2 = getUtility(ITeamMembershipSet).getByPersonAndTeam(
598 self.team1, self.team2)598 self.team1, self.team2)
599 self.assertEqual(team1_on_team2.status, TeamMembershipStatus.INVITED)599 self.assertEqual(team1_on_team2.status, TeamMembershipStatus.INVITED)
600600
=== modified file 'lib/lp/soyuz/browser/tests/archive-views.txt'
--- lib/lp/soyuz/browser/tests/archive-views.txt 2009-11-09 17:59:18 +0000
+++ lib/lp/soyuz/browser/tests/archive-views.txt 2010-01-05 17:55:34 +0000
@@ -957,7 +957,7 @@
957buildd_secret would leak through the public buildlogs.957buildd_secret would leak through the public buildlogs.
958958
959 >>> login('foo.bar@canonical.com')959 >>> login('foo.bar@canonical.com')
960 >>> a_team.addMember(cprov, mark)960 >>> ignored = a_team.addMember(cprov, mark)
961 >>> login('celso.providelo@canonical.com')961 >>> login('celso.providelo@canonical.com')
962962
963 >>> view = create_initialized_view(963 >>> view = create_initialized_view(
@@ -1186,7 +1186,7 @@
1186continue to be denied in the UI.1186continue to be denied in the UI.
11871187
1188 >>> login('foo.bar@canonical.com')1188 >>> login('foo.bar@canonical.com')
1189 >>> ubuntu.main_archive.owner.addMember(cprov, cprov)1189 >>> ignored = ubuntu.main_archive.owner.addMember(cprov, cprov)
1190 >>> login('celso.providelo@canonical.com')1190 >>> login('celso.providelo@canonical.com')
11911191
1192 >>> view = create_initialized_view(1192 >>> view = create_initialized_view(
11931193
=== modified file 'lib/lp/soyuz/browser/tests/build-views.txt'
--- lib/lp/soyuz/browser/tests/build-views.txt 2009-12-11 12:59:08 +0000
+++ lib/lp/soyuz/browser/tests/build-views.txt 2010-01-05 17:55:34 +0000
@@ -153,7 +153,7 @@
153 ... "launchpad-buildd-admins")153 ... "launchpad-buildd-admins")
154 >>> nopriv = getUtility(IPersonSet).getByName("no-priv")154 >>> nopriv = getUtility(IPersonSet).getByName("no-priv")
155 >>> login("foo.bar@canonical.com")155 >>> login("foo.bar@canonical.com")
156 >>> buildd_admins.addMember(nopriv, nopriv)156 >>> ignored = buildd_admins.addMember(nopriv, nopriv)
157157
158 >>> login("no-priv@canonical.com")158 >>> login("no-priv@canonical.com")
159 >>> failed_build_view = getMultiAdapter(159 >>> failed_build_view = getMultiAdapter(
160160
=== modified file 'lib/lp/soyuz/doc/archive.txt'
--- lib/lp/soyuz/doc/archive.txt 2009-12-25 07:54:31 +0000
+++ lib/lp/soyuz/doc/archive.txt 2010-01-05 17:55:34 +0000
@@ -1653,7 +1653,8 @@
16531653
1654But if we make him part of the uploader_team he'll gain access:1654But if we make him part of the uploader_team he'll gain access:
16551655
1656 >>> uploader_team.addMember(indirect_uploader, indirect_uploader)1656 >>> ignored = uploader_team.addMember(
1657 ... indirect_uploader, indirect_uploader)
1657 >>> for ppa in archive_set.getPPAsForUser(indirect_uploader):1658 >>> for ppa in archive_set.getPPAsForUser(indirect_uploader):
1658 ... print ppa.displayname1659 ... print ppa.displayname
1659 PPA for Celso Providelo1660 PPA for Celso Providelo
@@ -2249,7 +2250,7 @@
2249 >>> login('foo.bar@canonical.com')2250 >>> login('foo.bar@canonical.com')
2250 >>> ubuntu_security = getUtility(IPersonSet).getByName(2251 >>> ubuntu_security = getUtility(IPersonSet).getByName(
2251 ... 'ubuntu-security')2252 ... 'ubuntu-security')
2252 >>> ubuntu_security.addMember(carlos, cprov)2253 >>> ignored = ubuntu_security.addMember(carlos, cprov)
22532254
2254 >>> login('carlos@canonical.com')2255 >>> login('carlos@canonical.com')
2255 >>> check_permission('launchpad.Append', primary)2256 >>> check_permission('launchpad.Append', primary)
22562257
=== modified file 'lib/lp/soyuz/doc/archivepermission.txt'
--- lib/lp/soyuz/doc/archivepermission.txt 2009-09-18 09:29:49 +0000
+++ lib/lp/soyuz/doc/archivepermission.txt 2010-01-05 17:55:34 +0000
@@ -297,7 +297,7 @@
297Now add "test@canonical.com" to the techboard team and log in as him.297Now add "test@canonical.com" to the techboard team and log in as him.
298298
299 >>> person = personset.getByEmail("test@canonical.com")299 >>> person = personset.getByEmail("test@canonical.com")
300 >>> techboard.addMember(300 >>> ignored = techboard.addMember(
301 ... person, reviewer=person, status=TeamMembershipStatus.APPROVED,301 ... person, reviewer=person, status=TeamMembershipStatus.APPROVED,
302 ... force_team_add=True)302 ... force_team_add=True)
303 >>> login_person(person)303 >>> login_person(person)
304304
=== modified file 'lib/lp/soyuz/doc/archivesubscriber.txt'
--- lib/lp/soyuz/doc/archivesubscriber.txt 2009-08-13 19:03:36 +0000
+++ lib/lp/soyuz/doc/archivesubscriber.txt 2010-01-05 17:55:34 +0000
@@ -448,7 +448,8 @@
448indirect members that are not themselves groups are included:448indirect members that are not themselves groups are included:
449449
450 >>> launchpad_devs = getUtility(IPersonSet).getByName('launchpad')450 >>> launchpad_devs = getUtility(IPersonSet).getByName('launchpad')
451 >>> launchpad_devs.addMember(team_cprov, mark, force_team_add=True)451 >>> ignored = launchpad_devs.addMember(
452 ... team_cprov, mark, force_team_add=True)
452 >>> subscription = mark.archive.newSubscription(453 >>> subscription = mark.archive.newSubscription(
453 ... launchpad_devs, mark, description=u"LP team too")454 ... launchpad_devs, mark, description=u"LP team too")
454 >>> for person in subscription.getNonActiveSubscribers():455 >>> for person in subscription.getNonActiveSubscribers():
455456
=== modified file 'lib/lp/soyuz/doc/build-notification.txt'
--- lib/lp/soyuz/doc/build-notification.txt 2009-08-13 19:03:36 +0000
+++ lib/lp/soyuz/doc/build-notification.txt 2010-01-05 17:55:34 +0000
@@ -530,7 +530,7 @@
530 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')530 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
531 >>> team = factory.makeTeam(owner=cprov, email="team@example.com")531 >>> team = factory.makeTeam(owner=cprov, email="team@example.com")
532 >>> mark = failed_candidate.sourcepackagerelease.creator532 >>> mark = failed_candidate.sourcepackagerelease.creator
533 >>> team.addMember(mark, mark)533 >>> ignored = team.addMember(mark, mark)
534 >>> discard = pop_notifications() # Discard team join email.534 >>> discard = pop_notifications() # Discard team join email.
535 >>> team_ppa = factory.makeArchive(owner=team)535 >>> team_ppa = factory.makeArchive(owner=team)
536 >>> naked_candidate = removeSecurityProxy(failed_candidate)536 >>> naked_candidate = removeSecurityProxy(failed_candidate)
537537
=== modified file 'lib/lp/soyuz/doc/build.txt'
--- lib/lp/soyuz/doc/build.txt 2009-11-24 07:02:21 +0000
+++ lib/lp/soyuz/doc/build.txt 2010-01-05 17:55:34 +0000
@@ -837,7 +837,7 @@
837 >>> buildd_admin = factory.makePerson()837 >>> buildd_admin = factory.makePerson()
838 >>> buildd_admins = getUtility(838 >>> buildd_admins = getUtility(
839 ... IPersonSet).getByName('launchpad-buildd-admins')839 ... IPersonSet).getByName('launchpad-buildd-admins')
840 >>> buildd_admins.addMember(buildd_admin, buildd_admin)840 >>> ignored = buildd_admins.addMember(buildd_admin, buildd_admin)
841 >>> bob_builds = bob.getBuildRecords(user=buildd_admin)841 >>> bob_builds = bob.getBuildRecords(user=buildd_admin)
842 >>> print_build_details(bob_builds)842 >>> print_build_details(bob_builds)
843 ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE843 ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
@@ -845,9 +845,9 @@
845 ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE845 ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
846 ...846 ...
847 ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE847 ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
848 ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest 848 ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
849 RELEASE849 RELEASE
850 850
851 >>> bob_builds.count()851 >>> bob_builds.count()
852 13852 13
853853
854854
=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt'
--- lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 2009-08-31 02:52:41 +0000
+++ lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 2010-01-05 17:55:34 +0000
@@ -279,7 +279,7 @@
279 >>> beta_testers = getUtility(ILaunchpadCelebrities).launchpad_beta_testers279 >>> beta_testers = getUtility(ILaunchpadCelebrities).launchpad_beta_testers
280 >>> admin = getUtility(ILaunchpadCelebrities).admin280 >>> admin = getUtility(ILaunchpadCelebrities).admin
281 >>> name16 = getUtility(IPersonSet).getByName("name16")281 >>> name16 = getUtility(IPersonSet).getByName("name16")
282 >>> beta_testers.addMember(name16, admin)282 >>> ignored = beta_testers.addMember(name16, admin)
283283
284 >>> foobar_archive = getUtility(IArchiveSet).new(284 >>> foobar_archive = getUtility(IArchiveSet).new(
285 ... distribution=ubuntutest, purpose=ArchivePurpose.PPA,285 ... distribution=ubuntutest, purpose=ArchivePurpose.PPA,
286286
=== modified file 'lib/lp/soyuz/doc/packageset.txt'
--- lib/lp/soyuz/doc/packageset.txt 2009-08-13 15:12:16 +0000
+++ lib/lp/soyuz/doc/packageset.txt 2010-01-05 17:55:34 +0000
@@ -581,7 +581,7 @@
581581
582Now add "test@canonical.com" to the techboard team and log in as him.582Now add "test@canonical.com" to the techboard team and log in as him.
583583
584 >>> techboard.addMember(584 >>> ignored = techboard.addMember(
585 ... person2, reviewer=person2, status=TeamMembershipStatus.APPROVED,585 ... person2, reviewer=person2, status=TeamMembershipStatus.APPROVED,
586 ... force_team_add=True)586 ... force_team_add=True)
587 >>> login_person(person2)587 >>> login_person(person2)
588588
=== modified file 'lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt'
--- lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt 2009-09-14 07:56:54 +0000
+++ lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt 2010-01-05 17:55:34 +0000
@@ -273,7 +273,7 @@
273 >>> login('foo.bar@canonical.com')273 >>> login('foo.bar@canonical.com')
274 >>> foobar = getUtility(IPersonSet).getByName('name16')274 >>> foobar = getUtility(IPersonSet).getByName('name16')
275 >>> mark = getUtility(IPersonSet).getByName('mark')275 >>> mark = getUtility(IPersonSet).getByName('mark')
276 >>> launchpad.addMember(mark, foobar)276 >>> ignored = launchpad.addMember(mark, foobar)
277 >>> import transaction277 >>> import transaction
278 >>> transaction.commit()278 >>> transaction.commit()
279 >>> logout()279 >>> logout()
280280
=== modified file 'lib/lp/soyuz/stories/soyuz/xx-private-builds.txt'
--- lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2009-09-17 14:45:15 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2010-01-05 17:55:34 +0000
@@ -51,7 +51,7 @@
51 ... IPersonSet).getByName("launchpad-buildd-admins")51 ... IPersonSet).getByName("launchpad-buildd-admins")
52 >>> from lp.registry.interfaces.person import (52 >>> from lp.registry.interfaces.person import (
53 ... TeamMembershipStatus)53 ... TeamMembershipStatus)
54 >>> buildd_admins.addMember(54 >>> ignored = buildd_admins.addMember(
55 ... name12, reviewer=name12, status=TeamMembershipStatus.APPROVED)55 ... name12, reviewer=name12, status=TeamMembershipStatus.APPROVED)
5656
57 >>> flush_database_updates()57 >>> flush_database_updates()
5858
=== modified file 'lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt'
--- lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt 2009-09-19 08:30:29 +0000
+++ lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt 2010-01-05 17:55:34 +0000
@@ -97,7 +97,7 @@
97 >>> oofy = factory.makePerson(email='oofy@drones.example.com',97 >>> oofy = factory.makePerson(email='oofy@drones.example.com',
98 ... name='oofy', password='test', displayname='Oofy Prosser')98 ... name='oofy', password='test', displayname='Oofy Prosser')
99 >>> rosetta_admins = personset.getByName('rosetta-admins')99 >>> rosetta_admins = personset.getByName('rosetta-admins')
100 >>> rosetta_admins.addMember(oofy, carlos)100 >>> ignored = rosetta_admins.addMember(oofy, carlos)
101101
102 >>> gussie = factory.makePerson(email='gussie@drones.example.com',102 >>> gussie = factory.makePerson(email='gussie@drones.example.com',
103 ... name='gussie', password='test', displayname='Gussie Fink-Nottle')103 ... name='gussie', password='test', displayname='Gussie Fink-Nottle')