← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad.

Commit message:
Remove BranchPopupWidget, which only exists to create deprecated mirrored branches.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/remove-branch-popup-widget/+merge/324475
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/remove-branch-popup-widget into lp:launchpad.
=== removed file 'lib/lp/code/browser/widgets/branch.py'
--- lib/lp/code/browser/widgets/branch.py	2016-12-22 16:32:38 +0000
+++ lib/lp/code/browser/widgets/branch.py	1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-# Copyright 2011-2016 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-__metaclass__ = type
-
-__all__ = [
-    'AlreadyRegisteredError',
-    'BranchPopupWidget',
-    'NoProductError',
-    ]
-
-import sys
-
-from lazr.uri import (
-    InvalidURIError,
-    URI,
-    )
-from six import reraise
-from zope.component import getUtility
-from zope.formlib.interfaces import ConversionError
-
-from lp.app.browser.tales import BranchFormatterAPI
-from lp.app.validators import LaunchpadValidationError
-from lp.app.widgets.popup import VocabularyPickerWidget
-from lp.code.enums import BranchType
-from lp.code.interfaces.branch import IBranch
-from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.interfaces.branchnamespace import get_branch_namespace
-from lp.services.webapp.escaping import structured
-from lp.services.webapp.interfaces import ILaunchBag
-
-
-class AlreadyRegisteredError(Exception):
-    """Raised when we try to register an already-registered branch."""
-
-
-class NoProductError(Exception):
-    """Raised when we need a product and can't find one."""
-
-
-class BranchPopupWidget(VocabularyPickerWidget):
-    """Custom popup widget for choosing branches."""
-
-    displayWidth = '35'
-
-    def getBranchNameFromURL(self, url):
-        """Return a branch name based on `url`.
-
-        The name is based on the last path segment of the URL. If there is
-        already another branch of that name on the product, then we'll try to
-        find a unique name by appending numbers.
-        """
-        return URI(url).ensureNoSlash().path.split('/')[-1]
-
-    def getPerson(self):
-        """Return the person in the context, if any."""
-        return getUtility(ILaunchBag).user
-
-    def getProduct(self):
-        """Return the product in the context, if there is one."""
-        return getUtility(ILaunchBag).product
-
-    def makeBranchFromURL(self, url):
-        """Make a mirrored branch for `url`.
-
-        The product and owner of the branch are derived from information in
-        the launchbag. The name of the branch is derived from the last segment
-        of the URL and is guaranteed to be unique for the product.
-
-        :param url: The URL to mirror.
-        :return: An `IBranch`.
-        """
-        # XXX: JonathanLange 2008-12-08 spec=package-branches: This method
-        # needs to be rewritten to get the sourcepackage and distroseries out
-        # of the launch bag.
-        url = unicode(URI(url).ensureNoSlash())
-        if getUtility(IBranchLookup).getByUrl(url) is not None:
-            raise AlreadyRegisteredError('Already a branch for %r' % url)
-        # Make sure the URL is valid.
-        IBranch['url'].validate(url)
-        product = self.getProduct()
-        if product is None:
-            raise NoProductError("Could not find product in LaunchBag.")
-        owner = self.getPerson()
-        name = self.getBranchNameFromURL(url)
-        namespace = get_branch_namespace(person=owner, product=product)
-        branch = namespace.createBranchWithPrefix(
-            BranchType.MIRRORED, name, owner, url=url)
-        branch.requestMirror()
-        self.request.response.addNotification(
-            structured('Registered %s' %
-                       BranchFormatterAPI(branch).link(None)))
-        return branch
-
-    def _toFieldValue(self, form_input):
-        try:
-            return super(BranchPopupWidget, self)._toFieldValue(form_input)
-        except ConversionError:
-            # Save the initial error so we can re-raise it later.
-            exc_class, exc_obj, exc_tb = sys.exc_info()
-
-            # Try to register a branch, assuming form_input is a URL.
-            try:
-                return self.makeBranchFromURL(form_input)
-            except (InvalidURIError, NoProductError, AlreadyRegisteredError,
-                    LaunchpadValidationError):
-                # If it's not a URL or we can't figure out a product, then we
-                # re-raise the initial error.
-                reraise(exc_class, exc_obj, tb=exc_tb)

=== removed file 'lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py'
--- lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/widgets/tests/test_branchpopupwidget.py	1970-01-01 00:00:00 +0000
@@ -1,228 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Unit tests for Launchpad-specific widgets."""
-
-__metaclass__ = type
-
-import unittest
-
-from lazr.uri import URI
-from zope.component import (
-    getUtility,
-    provideUtility,
-    )
-from zope.formlib.interfaces import ConversionError
-from zope.interface import implementer
-from zope.schema import Choice
-
-from lp import _
-from lp.code.browser.widgets.branch import (
-    BranchPopupWidget,
-    NoProductError,
-    )
-from lp.code.enums import BranchType
-from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.vocabularies.branch import (
-    BranchRestrictedOnProductVocabulary,
-    BranchVocabulary,
-    )
-from lp.services.webapp.interfaces import ILaunchBag
-from lp.services.webapp.servers import LaunchpadTestRequest
-from lp.testing import (
-    ANONYMOUS,
-    login,
-    logout,
-    )
-from lp.testing.factory import LaunchpadObjectFactory
-from lp.testing.layers import LaunchpadFunctionalLayer
-
-
-@implementer(ILaunchBag)
-class DummyLaunchBag:
-    """Dummy LaunchBag that we can easily control in our tests."""
-
-    def __init__(self, user=None, product=None):
-        self.user = user
-        self.product = product
-
-
-class TestBranchPopupWidget(unittest.TestCase):
-    """Tests for the branch popup widget."""
-
-    layer = LaunchpadFunctionalLayer
-
-    def assertIs(self, first, second):
-        """Assert `first` is `second`."""
-        self.assertTrue(first is second, "%r is not %r" % (first, second))
-
-    def installLaunchBag(self, user=None, product=None):
-        bag = DummyLaunchBag(user, product)
-        provideUtility(bag, ILaunchBag)
-        return bag
-
-    def makeBranchPopup(self, vocabulary=None):
-        # Pick a random, semi-appropriate context.
-        context = self.factory.makeProduct()
-        if vocabulary is None:
-            vocabulary = BranchVocabulary(context)
-        request = self.makeRequest()
-        return BranchPopupWidget(
-            self.makeField(context, vocabulary), vocabulary, request)
-
-    def makeField(self, context, vocabulary):
-        field = Choice(
-            title=_('Branch'), vocabulary=vocabulary, required=False,
-            description=_("The Bazaar branch."))
-        field.context = context
-        return field
-
-    def makeRequest(self):
-        return LaunchpadTestRequest()
-
-    def setUp(self):
-        login(ANONYMOUS)
-        self._original_launch_bag = getUtility(ILaunchBag)
-        self.factory = LaunchpadObjectFactory()
-        self.launch_bag = self.installLaunchBag(
-            user=self.factory.makePerson(),
-            product=self.factory.makeProduct())
-        self.popup = self.makeBranchPopup()
-
-    def tearDown(self):
-        provideUtility(self._original_launch_bag, ILaunchBag)
-        logout()
-
-    def test_getProduct(self):
-        """getProduct() returns the product in the LaunchBag."""
-        self.assertEqual(self.launch_bag.product, self.popup.getProduct())
-
-    def test_getPerson(self):
-        """getPerson() returns the logged-in user."""
-        self.assertEqual(self.launch_bag.user, self.popup.getPerson())
-
-    def test_getBranchNameFromURL(self):
-        """getBranchNameFromURL() gets a branch name from a url.
-
-        In general, the name is the last path segment of the URL.
-        """
-        url = self.factory.getUniqueURL()
-        name = self.popup.getBranchNameFromURL(url)
-        self.assertEqual(URI(url).path.split('/')[-1], name)
-
-    def test_makeBranchFromURL(self):
-        """makeBranchFromURL(url) creates a mirrored branch at `url`.
-
-        The owner and registrant are the currently logged-in user, as given by
-        getPerson(), and the product is the product in the LaunchBag.
-        """
-        url = self.factory.getUniqueURL()
-        expected_name = self.popup.getBranchNameFromURL(url)
-        branch = self.popup.makeBranchFromURL(url)
-        self.assertEqual(BranchType.MIRRORED, branch.branch_type)
-        self.assertEqual(url, branch.url)
-        self.assertEqual(self.popup.getPerson(), branch.owner)
-        self.assertEqual(self.popup.getPerson(), branch.registrant)
-        self.assertEqual(self.popup.getProduct(), branch.product)
-        self.assertEqual(expected_name, branch.name)
-
-    def test_makeBranch_used(self):
-        # makeBranch makes up the branch name if the inferred one is already
-        # used.
-        url = self.factory.getUniqueURL()
-        expected_name = self.popup.getBranchNameFromURL(url)
-        self.factory.makeProductBranch(
-            name=expected_name, product=self.popup.getProduct(),
-            owner=self.popup.getPerson())
-        branch = self.popup.makeBranchFromURL(url)
-        self.assertEqual(expected_name + '-1', branch.name)
-
-    def test_makeBranchRequestsMirror(self):
-        """makeBranch requests a mirror on the branch it creates."""
-        url = self.factory.getUniqueURL()
-        branch = self.popup.makeBranchFromURL(url)
-        self.assertNotEqual('None', str(branch.next_mirror_time))
-
-    def test_makeBranchNoProduct(self):
-        """makeBranchFromURL(url) returns None if there's no product.
-
-        Not all contexts for branch registration have products. In particular,
-        a bug can be on a source package. When we link a branch to that bug,
-        there's no clear product to choose, so we don't choose any.
-        """
-        self.installLaunchBag(product=None, user=self.factory.makePerson())
-        url = self.factory.getUniqueURL()
-        self.assertRaises(NoProductError, self.popup.makeBranchFromURL, url)
-
-    def test_makeBranchTrailingSlash(self):
-        """makeBranch creates a mirrored branch even if the URL ends with /.
-        """
-        uri = URI(self.factory.getUniqueURL())
-        expected_name = self.popup.getBranchNameFromURL(
-            str(uri.ensureNoSlash()))
-        branch = self.popup.makeBranchFromURL(str(uri.ensureSlash()))
-        self.assertEqual(str(uri.ensureNoSlash()), branch.url)
-        self.assertEqual(expected_name, branch.name)
-
-    def test_toFieldValueFallsBackToMakingBranch(self):
-        """_toFieldValue falls back to making a branch if it's given a URL."""
-        url = self.factory.getUniqueURL()
-        # Check that there's no branch with this URL.
-        self.assertIs(None, getUtility(IBranchLookup).getByUrl(url))
-
-        branch = self.popup._toFieldValue(url)
-        self.assertEqual(url, branch.url)
-
-    def test_toFieldValueFetchesTheExistingBranch(self):
-        """_toFieldValue returns the existing branch that has that URL."""
-        expected_branch = self.factory.makeAnyBranch(
-            branch_type=BranchType.MIRRORED)
-        branch = self.popup._toFieldValue(expected_branch.url)
-        self.assertEqual(expected_branch, branch)
-
-    def test_toFieldValueNonURL(self):
-        """When the input isn't a URL, fall back to the original error."""
-        empty_search = 'doesntexist'
-        self.assertRaises(
-            ConversionError, self.popup._toFieldValue, empty_search)
-
-    def test_toFieldValueNoProduct(self):
-        """When there's no product, fall back to the original error."""
-        self.installLaunchBag(product=None, user=self.factory.makePerson())
-        self.assertRaises(
-            ConversionError, self.popup._toFieldValue,
-            self.factory.getUniqueURL())
-
-    def test_toFieldBadURL(self):
-        """When the input is a bad URL, fall back to the original error.
-
-        There are many valid URLs that are inappropriate for a mirrored
-        branch. We don't want to register a mirrored branch when someone
-        enters such a URL.
-        """
-        bad_url = 'svn://svn.example.com/repo/trunk'
-        self.assertRaises(ConversionError, self.popup._toFieldValue, bad_url)
-
-    def test_branchInRestrictedProduct(self):
-        # There are two reasons for a URL not being in the vocabulary. One
-        # reason is that it's there's no registered branch with that URL. The
-        # other is that the vocabulary on this form is restricted to one
-        # product, and there *is* a branch with that URL, but it's registered
-        # on a different product.
-
-        # Make a popup restricted to a particular product.
-        vocab = BranchRestrictedOnProductVocabulary(self.launch_bag.product)
-        self.assertEqual(vocab.product, self.launch_bag.product)
-        popup = self.makeBranchPopup(vocab)
-
-        # Make a branch on a different product.
-        branch = self.factory.makeProductBranch(
-            branch_type=BranchType.MIRRORED)
-        self.assertNotEqual(self.launch_bag.product, branch.product)
-
-        # Trying to make a branch with that URL will fail.
-        self.assertRaises(ConversionError, popup._toFieldValue, branch.url)
-
-    # XXX: JonathanLange 2008-04-17 bug=219019: Not sure how to test what
-    # happens when this widget has a good value but other fields have bad
-    # values. The correct behaviour is to *not* create the branch.

=== modified file 'lib/lp/code/stories/branches/xx-bug-branch-links.txt'
--- lib/lp/code/stories/branches/xx-bug-branch-links.txt	2017-04-18 22:17:00 +0000
+++ lib/lp/code/stories/branches/xx-bug-branch-links.txt	2017-05-23 13:39:50 +0000
@@ -138,60 +138,6 @@
     Undecided New
 
 
-Quick branch registration
-=========================
-
-You can also register a branch at the same time as registering a bug-branch
-link. Instead of entering the unique name of a branch, you can enter a URL:
-
-    >>> browser.open('http://bugs.launchpad.dev/thunderbird/+bug/15')
-    >>> printBugBranchLinks(browser)
-    No bug branch links
-
-If we go to register a branch and change our mind, there is a cancel
-link that points back to the bug page:
-
-    >>> browser.getLink('Link a related branch').click()
-    >>> cancel_link = browser.getLink('Cancel')
-    >>> cancel_link.url
-    'http://bugs.launchpad.dev/thunderbird/+bug/15'
-
-But we're here to register a branch:
-
-    >>> browser.getControl('Branch').value = (
-    ...     "http://example.org/branch";)
-    >>> browser.getControl('Continue').click()
-
-This registers a branch and links it to the bug:
-
-    >>> print_notifications(browser)
-    Registered lp://dev/~name12/thunderbird/branch
-    ...
-    >>> printBugBranchLinks(browser)
-    lp://dev/~name12/thunderbird/branch
-
-However, if the bug isn't on a project, we don't (can't!) register a branch.
-
-    >>> browser.open('http://launchpad.dev/bugs/10')
-    >>> printBugBranchLinks(browser)
-    No bug branch links
-
-Here we use 'http://example.org/branch2' as the URL. We have to use a
-different URL, since using an already-registered URL will just find that
-branch.
-
-    >>> browser.getLink('Link a related branch').click()
-    >>> browser.getControl('Branch').value = (
-    ...     "http://example.org/branch2";)
-    >>> browser.getControl('Continue').click()
-
-No bug-branch link is registered:
-
-    >>> browser.open('http://launchpad.dev/bugs/10')
-    >>> printBugBranchLinks(browser)
-    No bug branch links
-
-
 Deleting bug branch links
 =========================
 

=== modified file 'lib/lp/services/webapp/configure.zcml'
--- lib/lp/services/webapp/configure.zcml	2016-07-21 16:29:52 +0000
+++ lib/lp/services/webapp/configure.zcml	2017-05-23 13:39:50 +0000
@@ -403,16 +403,6 @@
       permission="zope.Public"
       />
 
-    <!-- Define the widget used by fields that use BranchVocabulary. -->
-    <view
-      type="zope.publisher.interfaces.browser.IBrowserRequest"
-      for="zope.schema.interfaces.IChoice
-        lp.code.vocabularies.branch.BranchVocabulary"
-      provides="zope.formlib.interfaces.IInputWidget"
-      factory="lp.code.browser.widgets.branch.BranchPopupWidget"
-      permission="zope.Public"
-      />
-
     <!-- Define the widget used by fields that use
          DistributionSourcePackageVocabulary. -->
     <view


Follow ups