launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #01916
lp:~edwin-grubbs/launchpad/bug-664788-configure-bugtracker-link-permission into lp:launchpad
Edwin Grubbs has proposed merging lp:~edwin-grubbs/launchpad/bug-664788-configure-bugtracker-link-permission into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#664788 "Configure bug tracker" link doesn't appear on project page for bug supervisor
https://bugs.launchpad.net/bugs/664788
Allow the bug supervisor to see the "Configure bug tracker" link on the project overview page.
--
https://code.launchpad.net/~edwin-grubbs/launchpad/bug-664788-configure-bugtracker-link-permission/+merge/40753
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~edwin-grubbs/launchpad/bug-664788-configure-bugtracker-link-permission into lp:launchpad.
=== modified file 'lib/canonical/launchpad/interfaces/__init__.py'
--- lib/canonical/launchpad/interfaces/__init__.py 2010-11-11 11:55:53 +0000
+++ lib/canonical/launchpad/interfaces/__init__.py 2010-11-12 20:00:43 +0000
@@ -10,3 +10,10 @@
package. Where possible, move things out of this package into better
locations under the 'lp' package. See the `lp` docstring for more details.
"""
+
+# XXX henninge 2010-11-12: This is needed by the file
+# +inbound-email-config.zcml which resides outside of the LP tree and can
+# only be safely updated at roll-out time. The import can be removed again
+# after the 10.11 roll-out.
+from canonical.launchpad.interfaces.mail import IMailHandler
+
=== modified file 'lib/lp/registry/browser/team.py'
--- lib/lp/registry/browser/team.py 2010-11-01 20:39:17 +0000
+++ lib/lp/registry/browser/team.py 2010-11-12 20:00:43 +0000
@@ -1075,6 +1075,8 @@
msg = "%s has been added as a member of this team." % (
newmember.unique_displayname)
self.request.response.addInfoNotification(msg)
+ # Clear the newmember widget so that the user can add another member.
+ self.widgets['newmember'].setRenderedValue(None)
class TeamMapView(LaunchpadView):
=== modified file 'lib/lp/registry/browser/tests/product-portlet-packages-view.txt'
--- lib/lp/registry/browser/tests/product-portlet-packages-view.txt 2010-10-19 18:44:31 +0000
+++ lib/lp/registry/browser/tests/product-portlet-packages-view.txt 2010-11-12 20:00:43 +0000
@@ -51,7 +51,9 @@
>>> print view.suggestions
[]
-The view does not set focus to its form otherwise it will cause the page to scroll.
+The view does not set focus to its form otherwise it will cause the page to
+scroll.
+
>>> view.focusedElementScript()
''
@@ -61,7 +63,7 @@
>>> content = find_tag_by_id(view.render(), 'portlet-packages')
>>> print extract_text(content)
All packages
- Packages in Ubuntu
+ Packages in Distributions
Launchpad doesn't know which Ubuntu packages this project
provides. Links from distribution packages to upstream projects
let distribution and upstream maintainers share bugs, patches, and
@@ -142,7 +144,7 @@
>>> print extract_text(content)
All packages
- Packages in Ubuntu
+ Packages in Distributions
Launchpad doesn't know which Ubuntu packages this project
provides. Links from distribution packages to upstream projects
let distribution and upstream maintainers share bugs, patches, and
@@ -185,7 +187,7 @@
>>> content = find_tag_by_id(view.render(), 'portlet-packages')
>>> print extract_text(content)
All packages
- Packages in Ubuntu
+ Packages in Distributions
Launchpad doesn't know which Ubuntu packages this project
provides. Links from distribution packages to upstream projects
let distribution and upstream maintainers share bugs, patches, and
=== modified file 'lib/lp/registry/browser/tests/test_product.py'
--- lib/lp/registry/browser/tests/test_product.py 2010-10-25 20:20:45 +0000
+++ lib/lp/registry/browser/tests/test_product.py 2010-11-12 20:00:43 +0000
@@ -6,22 +6,31 @@
__metaclass__ = type
import datetime
-import unittest
import pytz
+
+from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
+from canonical.config import config
+from canonical.launchpad.testing.pages import find_tag_by_id
from canonical.testing.layers import DatabaseFunctionalLayer
from lp.app.enums import ServiceUsage
from lp.registry.browser.product import ProductLicenseMixin
-from lp.registry.interfaces.product import License
+from lp.registry.interfaces.product import (
+ License,
+ IProductSet,
+ )
from lp.testing import (
login_person,
TestCaseWithFactory,
)
from lp.testing.mail_helpers import pop_notifications
from lp.testing.service_usage_helpers import set_service_usage
-from lp.testing.views import create_view
+from lp.testing.views import (
+ create_initialized_view,
+ create_view,
+ )
class TestProductLicenseMixin(TestCaseWithFactory):
@@ -135,5 +144,28 @@
self.assertTrue(view.registration_done)
-def test_suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
+class TestProductAddView(TestCaseWithFactory):
+ """Tests the configuration links and helpers."""
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestProductAddView, self).setUp()
+ self.product_set = getUtility(IProductSet)
+ # Marker allowing us to reset the config.
+ config.push(self.id(), '')
+ self.addCleanup(config.pop, self.id())
+
+ def test_staging_message_is_not_demo(self):
+ view = create_initialized_view(self.product_set, '+new')
+ message = find_tag_by_id(view.render(), 'staging-message')
+ self.assertTrue(message is not None)
+
+ def test_staging_message_is_demo(self):
+ config.push('staging-test', '''
+ [launchpad]
+ is_demo: true
+ ''')
+ view = create_initialized_view(self.product_set, '+new')
+ message = find_tag_by_id(view.render(), 'staging-message')
+ self.assertEqual(None, message)
=== modified file 'lib/lp/registry/browser/tests/test_team.py'
--- lib/lp/registry/browser/tests/test_team.py 2010-10-04 19:50:45 +0000
+++ lib/lp/registry/browser/tests/test_team.py 2010-11-12 20:00:43 +0000
@@ -5,7 +5,11 @@
from canonical.testing.layers import DatabaseFunctionalLayer
from lp.registry.browser.person import TeamOverviewMenu
-from lp.testing import TestCaseWithFactory
+from lp.testing import (
+ login_person,
+ TestCaseWithFactory,
+ person_logged_in,
+ )
from lp.testing.matchers import IsConfiguredBatchNavigator
from lp.testing.menu import check_menu_links
from lp.testing.views import create_initialized_view
@@ -50,3 +54,68 @@
self.assertThat(
view.held_messages,
IsConfiguredBatchNavigator('message', 'messages'))
+
+
+class TestTeamMemberAddView(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestTeamMemberAddView, self).setUp()
+ self.team = self.factory.makeTeam(name='test-team')
+ login_person(self.team.teamowner)
+
+ def getForm(self, new_member):
+ return {
+ 'field.newmember': new_member.name,
+ 'field.actions.add': 'Add Member',
+ }
+
+ def test_add_member_success(self):
+ member = self.factory.makePerson(name="a-member")
+ form = self.getForm(member)
+ view = create_initialized_view(self.team, "+addmember", form=form)
+ self.assertEqual([], view.errors)
+ notifications = view.request.response.notifications
+ self.assertEqual(1, len(notifications))
+ self.assertEqual(
+ 'A-member (a-member) has been added as a member of this team.',
+ notifications[0].message)
+ self.assertTrue(member.inTeam(self.team))
+ self.assertEqual(
+ None, view.widgets['newmember']._getCurrentValue())
+
+ def test_add_former_member_success(self):
+ member = self.factory.makePerson(name="a-member")
+ self.team.addMember(member, self.team.teamowner)
+ with person_logged_in(member):
+ member.leave(self.team)
+ form = self.getForm(member)
+ view = create_initialized_view(self.team, "+addmember", form=form)
+ self.assertEqual([], view.errors)
+ notifications = view.request.response.notifications
+ self.assertEqual(1, len(notifications))
+ self.assertEqual(
+ 'A-member (a-member) has been added as a member of this team.',
+ notifications[0].message)
+ self.assertTrue(member.inTeam(self.team))
+
+ def test_add_existing_member_fail(self):
+ member = self.factory.makePerson(name="a-member")
+ self.team.addMember(member, self.team.teamowner)
+ form = self.getForm(member)
+ view = create_initialized_view(self.team, "+addmember", form=form)
+ self.assertEqual(1, len(view.errors))
+ self.assertEqual(
+ "A-member (a-member) is already a member of Test Team.",
+ view.errors[0])
+
+ def test_add_empty_team_fail(self):
+ empty_team = self.factory.makeTeam(owner=self.team.teamowner)
+ self.team.teamowner.leave(empty_team)
+ form = self.getForm(empty_team)
+ view = create_initialized_view(self.team, "+addmember", form=form)
+ self.assertEqual(1, len(view.errors))
+ self.assertEqual(
+ "You can't add a team that doesn't have any active members.",
+ view.errors[0])
=== modified file 'lib/lp/registry/stories/product/xx-product-index.txt'
--- lib/lp/registry/stories/product/xx-product-index.txt 2010-10-09 16:36:22 +0000
+++ lib/lp/registry/stories/product/xx-product-index.txt 2010-11-12 20:00:43 +0000
@@ -359,7 +359,7 @@
>>> print extract_text(
... find_tag_by_id(user_browser.contents, 'portlet-packages'))
All packages
- Packages in Ubuntu
+ Packages in Distributions
âmozilla-firefoxâ source package in Warty Version 0.9 uploaded on...
A product that has linked packages now displays suggestions and asks
@@ -372,7 +372,7 @@
>>> print extract_text(
... find_tag_by_id(user_browser.contents, 'portlet-packages'))
All packages...
- Packages in Ubuntu...
+ Packages in Distributions...
Ubuntu Hoary packages:
pmount...
=== modified file 'lib/lp/registry/stories/teammembership/xx-add-member.txt'
--- lib/lp/registry/stories/teammembership/xx-add-member.txt 2010-10-09 16:36:22 +0000
+++ lib/lp/registry/stories/teammembership/xx-add-member.txt 2010-11-12 20:00:43 +0000
@@ -30,40 +30,6 @@
>>> cprov.inTeam(landscape_team)
True
-If the new member is already an approved member of that team, we'll say that.
-
- >>> browser.url
- 'http://launchpad.dev/%7Elandscape-developers/+addmember'
- >>> browser.getControl('New member').value = 'cprov'
- >>> browser.getControl('Add Member').click()
-
- >>> for tag in find_tags_by_class(browser.contents, 'message'):
- ... print tag.renderContents()
- There is 1 error.
- Celso Providelo (cprov) is already a member of Landscape Developers.
-
-On the other hand, if the member is among the inactive/proposed members of
-the team, we'll simply change the membership's status and say that it was
-successfully added.
-
- >>> from lp.registry.interfaces.teammembership import TeamMembershipStatus
- >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
- >>> login(ANONYMOUS) # login() because we need a zope interaction.
- >>> ignored = cprov_landscape_membership.setStatus(
- ... TeamMembershipStatus.DEACTIVATED, landscape_team.teamowner)
- >>> logout()
- >>> cprov_landscape_membership.syncUpdate()
-
- >>> browser.url
- 'http://launchpad.dev/%7Elandscape-developers/+addmember'
- >>> browser.getControl('New member').value = 'cprov'
- >>> browser.getControl('Add Member').click()
-
- >>> for tag in find_tags_by_class(browser.contents,
- ... 'informational message'):
- ... print tag.renderContents()
- Celso Providelo (cprov) has been added as a member of this team.
-
Adding teams
------------
@@ -217,36 +183,3 @@
... 'informational message'):
... print tag.renderContents()
This invitation has already been processed.
-
-
-Evil workarounds
-----------------
-
-One thing to keep in mind is that we can't invite a team without active
-members.
-XXX: This restriction was added as a workaround for
-https://launchpad.net/bugs/94164, but I don't think it's the correct fix for
-the bug sice we could skip the notification sent to the team in this case.
--- Guilherme Salgado, 2007-05-09
-
- # Ideally we should do this using the web UI, but doing it this way is a
- # lot simpler.
- >>> carlos = Person.byName('carlos')
- >>> ubuntu_translators = Person.byName('ubuntu-translators')
- >>> login(ANONYMOUS) # login() because we need a zope interaction.
- >>> carlos_translators_membership = TeamMembership.selectOneBy(
- ... personID=carlos.id, teamID=ubuntu_translators.id)
- >>> ignored = carlos_translators_membership.setStatus(
- ... TeamMembershipStatus.DEACTIVATED, ubuntu_translators.teamowner)
- >>> logout()
- >>> carlos_translators_membership.syncUpdate()
-
- >>> browser = setupBrowser(auth='Basic test@xxxxxxxxxxxxx:test')
- >>> browser.open('http://launchpad.dev/~landscape-developers/+addmember')
- >>> browser.getControl('New member').value = 'ubuntu-translators'
- >>> browser.getControl('Add Member').click()
-
- >>> for tag in find_tags_by_class(browser.contents, 'message'):
- ... print tag.renderContents()
- There is 1 error.
- You can't add a team that doesn't have any active members.
=== modified file 'lib/lp/registry/templates/person-editpgpkeys.pt'
--- lib/lp/registry/templates/person-editpgpkeys.pt 2010-10-26 22:40:11 +0000
+++ lib/lp/registry/templates/person-editpgpkeys.pt 2010-11-12 20:00:43 +0000
@@ -107,8 +107,12 @@
</div>
<div><input type="submit" value="Deactivate Key" /></div>
- <p><strong>Note:</strong> If you deactivate a key here, Launchpad will automatically disable any features that
- use that key, such as a signed code of conduct. Also, the key will be deactivated on Launchpad only.</p>
+ <p>
+ <strong>Note:</strong> deactivating a key in Launchpad disables all
+ Launchpad features that use that key such as signed codes of conduct.
+ Deactivating the key in Launchpad does not alter the key outside of
+ Launchpad.
+ </p>
</form>
=== modified file 'lib/lp/registry/templates/person-index.pt'
--- lib/lp/registry/templates/person-index.pt 2010-06-18 17:21:12 +0000
+++ lib/lp/registry/templates/person-index.pt 2010-11-12 20:00:43 +0000
@@ -19,23 +19,25 @@
<meta tal:condition="view/is_probationary_or_invalid_user"
name="robots" content="noindex,nofollow" />
<tal:openid_delegation condition="view/is_delegated_identity">
- <link rel="openid.server"
- href="https://login.launchpad.net/"
- tal:attributes="href view/openid_server_url" />
- <link rel="openid.delegate"
- href="https://login.launchpad.net/+id/xxxxxxxx"
- tal:attributes="href view/openid_identity_url" />
- <link rel="openid2.provider"
- href="https://login.launchpad.net/"
- tal:attributes="href view/openid_server_url" />
- <link rel="openid2.local_id"
- href="https://login.launchpad.net/+id/xxxxxxxx"
- tal:attributes="href view/openid_identity_url" />
-
- <meta http-equiv="X-XRDS-Location"
- content="https://login.launchpad.net/+id/xxxxxxx/+xrds"
- tal:attributes="content string:${view/openid_identity_url}/+xrds" />
-
+ <tal:has_openid_identity_url condition="view/openid_identity_url">
+ <link rel="openid.server"
+ href="https://login.launchpad.net/"
+ tal:attributes="href view/openid_server_url" />
+ <link rel="openid.delegate"
+ href="https://login.launchpad.net/+id/xxxxxxxx"
+ tal:attributes="href view/openid_identity_url" />
+ <link rel="openid2.provider"
+ href="https://login.launchpad.net/"
+ tal:attributes="href view/openid_server_url" />
+ <link rel="openid2.local_id"
+ href="https://login.launchpad.net/+id/xxxxxxxx"
+ tal:attributes="href view/openid_identity_url" />
+
+ <meta http-equiv="X-XRDS-Location"
+ content="https://login.launchpad.net/+id/xxxxxxx/+xrds"
+ tal:attributes="content string:${view/openid_identity_url}/+xrds"
+ />
+ </tal:has_openid_identity_url>
</tal:openid_delegation>
</tal:block>
</head>
=== modified file 'lib/lp/registry/templates/pillar-involvement-portlet.pt'
--- lib/lp/registry/templates/pillar-involvement-portlet.pt 2010-11-03 14:40:53 +0000
+++ lib/lp/registry/templates/pillar-involvement-portlet.pt 2010-11-12 20:00:43 +0000
@@ -31,6 +31,26 @@
</tal:disabled>
</ul>
+ <tal:pseudo-editor condition="not: context/required:launchpad.Edit">
+ <!--
+ The bug supervisor can view the "Configure bug tracker" link, but it
+ would be confusing to display the configuration progress
+ information.
+ -->
+ <table
+ tal:condition="view/configuration_links"
+ style="width: 100%; margin-top: 1em"
+ id="configuration_links">
+ <tal:item repeat="link_status view/configuration_links">
+ <tr>
+ <td>
+ <a tal:replace="structure link_status/link/fmt:link" />
+ </td>
+ </tr>
+ </tal:item>
+ </table>
+ </tal:pseudo-editor>
+
<tal:editor condition="context/required:launchpad.Edit"
define="registration view/registration_completeness">
=== modified file 'lib/lp/registry/templates/product-new.pt'
--- lib/lp/registry/templates/product-new.pt 2010-08-09 04:45:18 +0000
+++ lib/lp/registry/templates/product-new.pt 2010-11-12 20:00:43 +0000
@@ -239,9 +239,10 @@
});
</script>
- <div style="font-size: larger; background: #e0f0d0;
+ <div id="staging-message" style="font-size: larger; background: #e0f0d0;
padding: 0.3em; -moz-border-radius: 5px; -o-border-radius: 5px;
- -webkit-border-radius: 5px; margin-bottom: 1em;">
+ -webkit-border-radius: 5px; margin-bottom: 1em;"
+ tal:condition="not: is_demo">
You can <strong>test Launchpad's features</strong> at <a
href="https://staging.launchpad.net/">staging.launchpad.net</a>
<form style="display: inline; font-size: smaller"
=== modified file 'lib/lp/registry/templates/product-portlet-packages.pt'
--- lib/lp/registry/templates/product-portlet-packages.pt 2010-05-17 17:29:08 +0000
+++ lib/lp/registry/templates/product-portlet-packages.pt 2010-11-12 20:00:43 +0000
@@ -11,7 +11,7 @@
<span class="see-all"><a
tal:attributes="href context/menu:overview/packages/fmt:url">
All packages</a></span>
- Packages in Ubuntu
+ Packages in Distributions
</h2>
<tal:has_packages condition="packages">
=== modified file 'lib/lp/services/openid/adapters/openid.py'
--- lib/lp/services/openid/adapters/openid.py 2010-08-27 12:59:29 +0000
+++ lib/lp/services/openid/adapters/openid.py 2010-11-12 20:00:43 +0000
@@ -55,8 +55,11 @@
@property
def openid_identity_url(self):
"""See `IOpenIDPersistentIdentity`."""
+ openid_identifier = self.openid_identifier
+ if openid_identifier is None:
+ return None
identity_root_url = allvhosts.configs['openid'].rooturl
- return identity_root_url + self.openid_identifier.encode('ascii')
+ return identity_root_url + openid_identifier.encode('ascii')
@property
def openid_identifier(self):
=== modified file 'utilities/sourcedeps.conf'
--- utilities/sourcedeps.conf 2010-11-10 16:56:40 +0000
+++ utilities/sourcedeps.conf 2010-11-12 20:00:43 +0000
@@ -15,4 +15,4 @@
subvertpy lp:~launchpad-pqm/subvertpy/trunk;revno=2042
python-debian lp:~launchpad-pqm/python-debian/devel;revno=185
testresources lp:~launchpad-pqm/testresources/dev;revno=16
-shipit lp:~launchpad-pqm/shipit/trunk;revno=8920 optional
+shipit lp:~launchpad-pqm/shipit/trunk;revno=8921 optional