launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #00262
[Merge] lp:~sinzui/launchpad/bugtask-set-packaging-0 into lp:launchpad/devel
Curtis Hovey has proposed merging lp:~sinzui/launchpad/bugtask-set-packaging-0 into lp:launchpad/devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
This is my branch to create a packaging during the bug-also-affects process.
lp:~sinzui/launchpad/bugtask-set-packaging-0
Diff size: 454
Launchpad bug:
https://bugs.launchpad.net/bugs/184077
Test command: ./bin/test -vv \
-t test_bugtask_adding -t bugtask-adding-views
Pre-implementation: Deryck, Bryce, Brian
Target release: 10.08
Create a packaging during the bug-also-affects process
------------------------------------------------------
When using the bug-also-affect process to add a BugTask, and there
is no Packaging link, the user is asked to locate the upstream/downstream,
and a notification is show suggesting that the step could be avoided by
creating a Packaging link. This is a bad experience, because the notification
takes the user away his goal. This is also bad because the Packaging link
process is very similar the the bug-also-affects process.
They user could state that the select upstream/downstream is the default
and Launchpad would create the Packaging link when the BugTask is added.
Rules
-----
* Add a checkbox to the base also-affect form so that the user can
indicate that the link should be created
[X] Link the package to the upstream project?
Always suggest this project when adding an upstream bug for this
package.
* Show the checkbox when the user is using affect project from a
source package.
* Show the checkbox when the user chooses to register a new project.
* Show the checkbox when the user
QA
--
* Visit a unlinked package with a bug.
* Choose also affects project
* Locate a project and select
[X] Link the package to the upstream project?
* Complete for form
* Verify that the project is linked on the packages overview page.
* Visit a unlinked package with a bug.
* Choose also affects project
* Choose to register a new project
* Select
[X] Link the package to the upstream project?
* Complete for form
* Verify that the project is linked on the packages overview page.
Lint
----
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/bugs/browser/bugalsoaffects.py
lib/lp/bugs/browser/tests/bugtask-adding-views.txt
lib/lp/bugs/browser/tests/test_bugtask_adding.py
lib/lp/bugs/interfaces/bugtask.py
lib/lp/bugs/templates/bugtask-affects-new-product.pt
lib/lp/bugs/templates/bugtask-requestfix-upstream.pt
^ There is lint in
lib/lp/bugs/browser/tests/bugtask-adding-views.txt
lib/lp/bugs/interfaces/bugtask.py
that I can clean up after the review
Test
----
* lib/lp/bugs/browser/tests/bugtask-adding-views.txt
* Removed the obsolete test for the packaging notice.
* Updated to form to work with the new changes.
* I may be able to delete some redundant parts of this this test. It
looked like some tinkering was need to remove parts and keep other
parts still working.
* lib/lp/bugs/browser/tests/test_bugtask_adding.py
* Added new tests to verify when the add_packaging field is available
and to verify when a packaging link is created.
Implementation
--------------
* lib/lp/bugs/browser/bugalsoaffects.py
* Replaced the field_names attribute with a property to include
add_packaging when there is not packaging link.
* Removed obsolete packaging link notice.
* Added the add_packaging field to some of the steps to ensure the
value is passed to the final step
* Added a rule to create a packaging link.
* lib/lp/bugs/interfaces/bugtask.py
* Added add_packaging to the choose product and register product
interfaces.
* lib/lp/bugs/templates/bugtask-affects-new-product.pt
* Added a field to collect the value of add_packaging if it can be
used.
* lib/lp/bugs/templates/bugtask-requestfix-upstream.pt
* Added a field to pass the hidden value of add_packaging
--
https://code.launchpad.net/~sinzui/launchpad/bugtask-set-packaging-0/+merge/30861
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/bugtask-set-packaging-0 into lp:launchpad/devel.
=== modified file 'lib/lp/bugs/browser/bugalsoaffects.py'
--- lib/lp/bugs/browser/bugalsoaffects.py 2010-04-23 20:10:48 +0000
+++ lib/lp/bugs/browser/bugalsoaffects.py 2010-07-24 19:51:11 +0000
@@ -38,6 +38,7 @@
IBugWatchSet, NoBugTrackerFound, UnrecognizedBugTrackerURL)
from lp.registry.interfaces.distributionsourcepackage import (
IDistributionSourcePackage)
+from lp.registry.interfaces.packaging import IPackagingUtil, PackagingType
from lp.registry.interfaces.product import (IProductSet, License)
from canonical.launchpad.validators import LaunchpadValidationError
from canonical.launchpad.validators.email import email_validator
@@ -80,10 +81,24 @@
'../templates/bugtask-choose-affected-product.pt')
custom_widget('product', SearchForUpstreamPopupWidget)
- _field_names = ['product']
label = u"Record as affecting another project"
step_name = "choose_product"
+ @property
+ def can_link_package(self):
+ bugtask = self.context
+ is_package_bugtask = IDistributionSourcePackage.providedBy(
+ bugtask.target)
+ return is_package_bugtask and bugtask.target.upstream_product is None
+
+ @property
+ def _field_names(self):
+ """The fields needed to choose an existing project."""
+ names = ['product']
+ if self.can_link_package:
+ names.append('add_packaging')
+ return names
+
def initialize(self):
super(ChooseProductStep, self).initialize()
if (self.widgets['product'].hasInput() or
@@ -113,27 +128,10 @@
# so we can go straight to the page asking for the remote
# bug URL.
self.request.form['field.product'] = upstream.name
+ self.request.form['field.add_packaging'] = 'off'
self.next_step = ProductBugTaskCreationStep
return
- distroseries = bugtask.distribution.currentseries
- if distroseries is not None:
- sourcepackage = distroseries.getSourcePackage(
- bugtask.sourcepackagename)
-
- self.request.response.addInfoNotification(
- self._needProjectNotice(bugtask, sourcepackage))
-
- def _needProjectNotice(self, bugtask, sourcepackage):
- return structured(
- _("""
- Please select the appropriate upstream project. This step can
- be avoided by <a href="%(package_url)s/+edit-packaging"
- >updating the packaging information for
- %(full_package_name)s</a>."""),
- full_package_name=bugtask.bugtargetdisplayname,
- package_url=canonical_url(sourcepackage))
-
def validateStep(self, data):
if data.get('product'):
try:
@@ -155,7 +153,7 @@
self.setFieldError(
'product',
structured("""
- There is no project in Launchpad named "%s". Please
+ There is no project in Launchpad named "%s". Please
<a href="/projects"
onclick="YUI().use('event').Event.simulate(
document.getElementById('%s'), 'click');
@@ -169,6 +167,10 @@
# Inject the selected product into the form and set the next_step to
# be used by our multistep controller.
self.request.form['field.product'] = data['product'].name
+ if data.get('add_packaging', False):
+ self.request.form['field.add_packaging'] = 'on'
+ else:
+ self.request.form['field.add_packaging'] = 'off'
self.next_step = ProductBugTaskCreationStep
@@ -234,7 +236,7 @@
except NoBugTrackerFound:
# Delegate to another view which will ask the user if (s)he
# wants to create the bugtracker now.
- if list(self.target_field_names) == ['product']:
+ if 'product' in self.target_field_names:
self.next_step = UpstreamBugTrackerCreationStep
else:
assert 'distribution' in self.target_field_names
@@ -488,7 +490,7 @@
'../templates/bugtask-requestfix-upstream.pt')
label = "Confirm project"
- target_field_names = ('product',)
+ target_field_names = ('product', 'add_packaging')
main_action_label = u'Add to Bug Report'
schema = IAddBugTaskWithUpstreamLinkForm
@@ -523,8 +525,7 @@
LinkUpstreamHowOptions.LINK_UPSTREAM:
'bug_url',
LinkUpstreamHowOptions.EMAIL_UPSTREAM_DONE:
- 'upstream_email_address_done'
- }
+ 'upstream_email_address_done'}
# Examine the radio group if it has valid input.
link_upstream_how = self.widgets['link_upstream_how']
@@ -596,7 +597,15 @@
getUtility(IBugTrackerSet).ensureBugTracker(
bug_url, self.user, BugTrackerType.EMAILADDRESS)
data['bug_url'] = bug_url
-
+ if data.get('add_packaging', False):
+ # Create a packaging link so that Launchpad will suggest the
+ # upstream project to the user.
+ packaging_util = getUtility(IPackagingUtil)
+ packaging_util.createPackaging(
+ productseries=data['product'].development_focus,
+ sourcepackagename=self.context.target.sourcepackagename,
+ distroseries=self.context.target.distribution.currentseries,
+ packaging=PackagingType.PRIME, owner=self.user)
return super(ProductBugTaskCreationStep, self).main_action(data)
@property
@@ -680,11 +689,25 @@
schema = IAddBugTaskWithProductCreationForm
custom_widget('bug_url', StrippedTextWidget, displayWidth=62)
custom_widget('existing_product', LaunchpadRadioWidget)
- field_names = ['bug_url', 'displayname', 'name', 'summary']
existing_products = None
MAX_PRODUCTS_TO_DISPLAY = 10
licenses = [License.DONT_KNOW]
+ @property
+ def can_link_package(self):
+ bugtask = self.context
+ is_package_bugtask = IDistributionSourcePackage.providedBy(
+ bugtask.target)
+ return is_package_bugtask and bugtask.target.upstream_product is None
+
+ @property
+ def field_names(self):
+ """The fields needed to choose an existing project."""
+ names = ['bug_url', 'displayname', 'name', 'summary']
+ if self.can_link_package:
+ names.append('add_packaging')
+ return names
+
def _loadProductsUsingBugTracker(self):
"""Find products using the bugtracker wich runs on the given URL.
@@ -791,8 +814,7 @@
name=data['name'],
displayname=data['displayname'], title=data['displayname'],
summary=data['summary'], licenses=self.licenses,
- registrant=self.user
- )
+ registrant=self.user)
data['product'] = product
self._createBugTaskAndWatch(data, set_bugtracker=True)
# Now that the product is configured set the owner to be the registry
=== modified file 'lib/lp/bugs/browser/tests/bugtask-adding-views.txt'
--- lib/lp/bugs/browser/tests/bugtask-adding-views.txt 2010-04-23 20:10:48 +0000
+++ lib/lp/bugs/browser/tests/bugtask-adding-views.txt 2010-07-24 19:51:11 +0000
@@ -29,6 +29,7 @@
>>> add_task_view = get_and_setup_view(
... firefox_task, '+choose-affected-product', form={}, method='GET')
+
We haven't posted the form, so we'll see one button.
>>> [action.label for action in add_task_view.actions]
@@ -65,6 +66,7 @@
>>> form = {
... 'field.actions.continue': '', 'field.product': 'evolution',
+ ... 'field.add_packaging': 'off',
... 'field.__visited_steps__': 'choose_product'}
>>> add_task_view = get_and_setup_view(
... firefox_task, '+choose-affected-product', form)
@@ -118,8 +120,8 @@
u'firefox'
If some package doesn't have a packaging link, a product will have to
-be chosen manually, and a notification will be displayed, explaining
-why the product wasn't chosen automatically.
+be chosen manually, and the user may choose to link the package to the
+project..
>>> ubuntu_thunderbird = ubuntu.getSourcePackage('thunderbird')
>>> thunderbird_bug = ubuntu_thunderbird.createBug(create_params)
@@ -131,13 +133,11 @@
>>> add_task_view.step_name
'choose_product'
+ >>> add_task_view.field_names
+ ['product', 'add_packaging', '__visited_steps__']
+
>>> print add_task_view.widgets['product']._getFormInput()
None
- >>> len(add_task_view.request.response.notifications)
- 1
- >>> for notification in add_task_view.request.response.notifications:
- ... print notification.message
- Please select the appropriate upstream project. This step...
Sometimes the distribution won't have any series, though. In that
case, we won't prompt the user to add a link, since he can't actually
@@ -187,6 +187,7 @@
>>> form = {
... 'field.actions.continue': '1',
... 'field.product': u'no-such-product',
+ ... 'field.add_packaging': 'off',
... 'field.__visited_steps__':
... 'choose_product|specify_remote_bug_url',
... }
@@ -602,6 +603,7 @@
>>> form = {
... 'field.actions.continue': '', 'field.product': 'frobnitz',
+ ... 'field.add_packaging': 'off',
... 'field.__visited_steps__': 'choose_product'}
>>> add_task_view = get_and_setup_view(
... firefox_task, '+choose-affected-product', form)
=== added file 'lib/lp/bugs/browser/tests/test_bugtask_adding.py'
--- lib/lp/bugs/browser/tests/test_bugtask_adding.py 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/browser/tests/test_bugtask_adding.py 2010-07-24 19:51:11 +0000
@@ -0,0 +1,158 @@
+# Copyright 2010 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+__metaclass__ = type
+
+
+from zope.component import getUtility
+
+from lp.registry.interfaces.packaging import IPackagingUtil, PackagingType
+from lp.testing import TestCaseWithFactory
+from lp.testing.views import create_initialized_view
+
+from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
+from canonical.launchpad.ftests import login_person
+from canonical.testing import DatabaseFunctionalLayer
+
+
+class TestProductBugTaskCreationStep(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestProductBugTaskCreationStep, self).setUp()
+ ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
+ self.ubuntu_series = ubuntu['hoary']
+ self.sourcepackagename = self.factory.makeSourcePackageName('bat')
+ self.sourcepackage = self.factory.makeSourcePackage(
+ sourcepackagename=self.sourcepackagename,
+ distroseries=self.ubuntu_series)
+ self.distrosourcepackage = self.factory.makeDistributionSourcePackage(
+ sourcepackagename=self.sourcepackagename, distribution=ubuntu)
+ self.factory.makeSourcePackagePublishingHistory(
+ sourcepackagename=self.sourcepackagename,
+ distroseries=self.ubuntu_series)
+ self.product = self.factory.makeProduct(name="bat")
+ self.packaging_util = getUtility(IPackagingUtil)
+ self.user = self.factory.makePerson()
+ login_person(self.user)
+ self.bug_task = self.factory.makeBugTask(
+ target=self.distrosourcepackage, owner=self.user)
+ self.bug = self.bug_task.bug
+
+ def test_choose_product_when_packaging_does_not_exist(self):
+ # Verify the view is on the first step and that it includes the
+ # add_packaging field.
+ view = create_initialized_view(
+ self.bug_task, '+choose-affected-product')
+ self.assertEqual('choose_product', view.view.step_name)
+ self.assertEqual(
+ ['product', 'add_packaging', '__visited_steps__'],
+ view.view.field_names)
+
+ def test_choose_product_when_packaging_does_exist(self):
+ # Verify the view is on the second step and that the add_packaging
+ # field was set to False.
+ self.packaging_util.createPackaging(
+ self.product.development_focus, self.sourcepackagename,
+ self.ubuntu_series, PackagingType.PRIME, self.user)
+ view = create_initialized_view(
+ self.bug_task, '+choose-affected-product')
+ self.assertEqual('specify_remote_bug_url', view.view.step_name)
+ field_names = [
+ 'link_upstream_how', 'upstream_email_address_done', 'bug_url',
+ 'product', 'add_packaging', '__visited_steps__']
+ self.assertEqual(field_names, view.view.field_names)
+ add_packaging_field = view.view.widgets['add_packaging']
+ self.assertEqual(False, add_packaging_field.getInputValue())
+
+ def test_rechoose_product_when_packaging_does_exist(self):
+ # Verify the user can rechoose the product (the first step) and that
+ # the add_packaging field is not included when the package is linked.
+ self.packaging_util.createPackaging(
+ self.product.development_focus, self.sourcepackagename,
+ self.ubuntu_series, PackagingType.PRIME, self.user)
+ form = {'field.product': 'bat'}
+ view = create_initialized_view(
+ self.bug_task, '+choose-affected-product', form=form)
+ self.assertEqual('choose_product', view.view.step_name)
+ field_names = ['product', '__visited_steps__']
+ self.assertEqual(field_names, view.view.field_names)
+
+ def test_create_upstream_bugtask_without_packaging(self):
+ # Verify that the project has a new bugtask and no packaging link.
+ form = {
+ 'field.product': 'bat',
+ 'field.add_packaging': 'off',
+ 'field.__visited_steps__':
+ 'choose_product|specify_remote_bug_url',
+ 'field.actions.continue': 'Continue',
+ }
+ view = create_initialized_view(
+ self.bug_task, '+choose-affected-product', form=form)
+ self.assertEqual([], view.view.errors)
+ self.assertTrue(self.bug.getBugTask(self.product) is not None)
+ has_packaging = self.packaging_util.packagingEntryExists(
+ self.sourcepackagename, self.ubuntu_series,
+ self.product.development_focus)
+ self.assertFalse(has_packaging)
+
+ def test_create_upstream_bugtask_with_packaging(self):
+ # Verify that the project has a new bugtask and packaging link.
+ form = {
+ 'field.product': 'bat',
+ 'field.add_packaging': 'on',
+ 'field.__visited_steps__':
+ 'choose_product|specify_remote_bug_url',
+ 'field.actions.continue': 'Continue',
+ }
+ view = create_initialized_view(
+ self.bug_task, '+choose-affected-product', form=form)
+ self.assertEqual([], view.view.errors)
+ self.assertTrue(self.bug.getBugTask(self.product) is not None)
+ has_packaging = self.packaging_util.packagingEntryExists(
+ self.sourcepackagename, self.ubuntu_series,
+ self.product.development_focus)
+ self.assertTrue(has_packaging)
+
+ def test_register_product_fields_packaging_exists(self):
+ # The view includes the add_packaging field.
+ view = create_initialized_view(
+ self.bug_task, '+affects-new-product')
+ self.assertEqual(
+ ['bug_url', 'displayname', 'name', 'summary', 'add_packaging'],
+ view.field_names)
+
+ def test_register_product_fields_packaging_does_not_exist(self):
+ # The view does not include the add_packaging field.
+ self.packaging_util.createPackaging(
+ self.product.development_focus, self.sourcepackagename,
+ self.ubuntu_series, PackagingType.PRIME,
+ self.user)
+ view = create_initialized_view(
+ self.bug_task, '+affects-new-product')
+ self.assertEqual(
+ ['bug_url', 'displayname', 'name', 'summary'],
+ view.field_names)
+
+ def test_register_project_create_upstream_bugtask_with_packaging(self):
+ # Verify the new project has a bug task and packaging link.
+ form = {
+ 'field.bug_url': 'http://bugs.foo.org/bugs/show_bug.cgi?id=8',
+ 'field.name': 'fruit',
+ 'field.displayname': 'Fruit',
+ 'field.summary': 'The Fruit summary',
+ 'field.add_packaging': 'on',
+ 'field.actions.continue': 'Continue',
+ }
+ view = create_initialized_view(
+ self.bug_task, '+affects-new-product', form=form)
+ self.assertEqual([], view.errors)
+ targets = [bugtask.target for bugtask in self.bug.bugtasks
+ if bugtask.target.name == 'fruit']
+ self.assertEqual(1, len(targets))
+ product = targets[0]
+ has_packaging = self.packaging_util.packagingEntryExists(
+ self.sourcepackagename, self.ubuntu_series,
+ product.development_focus)
+ self.assertTrue(has_packaging)
=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
--- lib/lp/bugs/interfaces/bugtask.py 2010-06-25 15:03:10 +0000
+++ lib/lp/bugs/interfaces/bugtask.py 2010-07-24 19:51:11 +0000
@@ -1494,6 +1494,11 @@
bug_url = StrippedTextLine(
title=_('URL'), required=False, constraint=valid_remote_bug_url,
description=_("The URL of this bug in the remote bug tracker."))
+ add_packaging = Bool(
+ title=_('Link the package to the upstream project?'),
+ description=_('Always suggest this project when adding an '
+ 'upstream bug for this package.'),
+ required=True, default=False)
class IAddBugTaskWithProductCreationForm(Interface):
@@ -1509,6 +1514,11 @@
"followed by letters, dots, hyphens or plusses. e.g. firefox, "
"linux, gnome-terminal."))
summary = Summary(title=_('Project summary'), required=True)
+ add_packaging = Bool(
+ title=_('Link the package to the upstream project?'),
+ description=_('Always suggest this project when adding an '
+ 'upstream bug for this package.'),
+ required=True, default=False)
class INominationsReviewTableBatchNavigator(ITableBatchNavigator):
=== modified file 'lib/lp/bugs/templates/bugtask-affects-new-product.pt'
--- lib/lp/bugs/templates/bugtask-affects-new-product.pt 2010-07-02 16:21:46 +0000
+++ lib/lp/bugs/templates/bugtask-affects-new-product.pt 2010-07-24 19:51:11 +0000
@@ -64,6 +64,12 @@
<tal:product-summary define="widget nocall:widgets/summary">
<metal:block use-macro="context/@@launchpad_form/widget_row" />
</tal:product-summary>
+
+ <tal:can_link_package condition="view/can_link_package">
+ <tal:add-packaging define="widget nocall:widgets/add_packaging">
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ </tal:add-packaging>
+ </tal:can_link_package>
</table>
<div class="actions">
=== modified file 'lib/lp/bugs/templates/bugtask-requestfix-upstream.pt'
--- lib/lp/bugs/templates/bugtask-requestfix-upstream.pt 2009-09-08 09:25:58 +0000
+++ lib/lp/bugs/templates/bugtask-requestfix-upstream.pt 2010-07-24 19:51:11 +0000
@@ -36,6 +36,8 @@
<tal:visited_steps
replace="structure view/widgets/__visited_steps__/hidden" />
+ <tal:add_packaging
+ replace="structure view/widgets/add_packaging/hidden" />
<div class="field">