> Hi Edwin, > > This is nice, and it's good to see some XXXs go in the process. The > view code with the Storm validator as a backstop is elegant. > > I've got a few questions and comments, so Needs Information for now. > > Cheers, Gavin. > Hi Gavin and Brad, Thanks for the reviews. The incremental diff is in the previous comment. > > === modified file 'lib/lp/registry/browser/product.py' > > --- lib/lp/registry/browser/product.py 2010-04-14 17:16:56 +0000 > > +++ lib/lp/registry/browser/product.py 2010-04-21 11:03:32 +0000 > > @@ -1444,6 +1444,15 @@ > > """See `LaunchpadFormView`.""" > > self.validate_private_bugs(data) > > > > + if data['active'] == False and self.context.active == True: > > + if len(self.context.sourcepackages) > 0: > > + self.setFieldError('active', > > + structured( > > + 'This project cannot be deactivated since it is ' > > + 'linked to ' > > + 'source packages.', > > + canonical_url(self.context))) > > You could change this to instead pass view_name='+packages' to > canonical_url(). Fixed. > It is worth showing this message before the user tries to deactivate > the project? Perhaps a message next to the control, and the control > disabled. That's a nice idea, however, the validation would still be necessary for race conditions when the form is displayed before the source package is linked. Since deactivation will be done much more often by reviewers than regular users, I don't know if it is worth it. I believe Curtis still reviews most of the projects, so I'll ask him. > Also, the text "This project cannot be deactivated since it is linked > to source packages" doesn't sound quite right. How about "... linked > to one or more source packages"? Fixed. > Perhaps it's worth getting a UI review? Since I'm already talking to Curtis, and he's a UI reviewer, I'll ask him. > > + > > @property > > def cancel_url(self): > > """See `LaunchpadFormView`.""" > > @@ -1491,6 +1500,15 @@ > > # supervisor. > > self.validate_private_bugs(data) > > > > + if data['active'] == False and self.context.active == True: > > + if len(self.context.sourcepackages) > 0: > > + self.setFieldError('active', > > + structured( > > + 'This project cannot be deactivated since it is ' > > + 'linked to ' > > + 'source packages.', > > + canonical_url(self.context))) > > Same here, re. view_name. > > ProductReviewLicenseView.validate() uses the same validation code as > in ProductAdminView.validate(). Consider putting this in a mixin class > that both ProductAdminView and ProductReviewLicenseView can use. Done. > > + > > > > class ProductAddSeriesView(LaunchpadFormView): > > """A form to add new product series""" > > > > === modified file 'lib/lp/registry/tests/test_product.py' > > --- lib/lp/registry/tests/test_product.py 2009-10-23 13:48:28 +0000 > > +++ lib/lp/registry/tests/test_product.py 2010-04-21 11:03:32 +0000 > > @@ -19,13 +19,39 @@ > > from canonical.launchpad.ftests import syncUpdate > > > > from lp.registry.interfaces.person import IPersonSet > > -from lp.registry.interfaces.product import License > > +from lp.registry.interfaces.product import IProductSet, License > > from lp.registry.model.product import Product > > from lp.registry.model.productlicense import ProductLicense > > from lp.registry.model.commercialsubscription import ( > > CommercialSubscription) > > from lp.testing import TestCaseWithFactory > > > > +class TestProduct(TestCaseWithFactory): > > + """Tests product object.""" > > + > > + layer = LaunchpadFunctionalLayer > > + > > + def test_deactivation_failure(self): > > + # Ensure that a product cannot be deactivated if > > + # it is linked to source packages. > > + login('