Hi Michael, I have moved the full test to unit testing layer and listed the series sorted alphabetically. When you have time, please take a look at the latest diff. No hurry. Thanks! === modified file 'lib/lp/translations/browser/product.py' --- lib/lp/translations/browser/product.py 2010-01-28 09:11:58 +0000 +++ lib/lp/translations/browser/product.py 2010-01-28 14:21:11 +0000 @@ -85,7 +85,7 @@ @cachedproperty def uses_translations(self): """Whether this product has translatable templates.""" - return (self.context.official_rosetta and + return (self.context.official_rosetta and self.primary_translatable is not None) @cachedproperty @@ -114,13 +114,15 @@ @cachedproperty def untranslatable_series(self): """Return series which are not yet set up for translations. - - Obsolete series will be excluded from this list. + + The list is sorted in alphabetically order and obsolete series + will be excluded. """ all_active_series = set( [serie for serie in self.context.series if ( serie.status != SeriesStatus.OBSOLETE)]) translatable = set(self.context.translatable_series) - return all_active_series - translatable - + return sorted( + all_active_series - translatable, + key=lambda series: series.name) === modified file 'lib/lp/translations/browser/tests/test_product_view.py' --- lib/lp/translations/browser/tests/test_product_view.py 2010-01-16 08:45:58 +0000 +++ lib/lp/translations/browser/tests/test_product_view.py 2010-01-28 14:20:51 +0000 @@ -9,6 +9,7 @@ from canonical.testing import LaunchpadZopelessLayer from lp.translations.browser.product import ProductView from lp.testing import TestCaseWithFactory +from lp.registry.interfaces.series import SeriesStatus class TestProduct(TestCaseWithFactory): @@ -17,27 +18,82 @@ layer = LaunchpadZopelessLayer def setUp(self): - # Create a product that uses translations. TestCaseWithFactory.setUp(self) - self.product = self.factory.makeProduct() - self.series = self.product.development_focus - self.product.official_rosetta = True - self.view = ProductView(self.product, - LaunchpadTestRequest()) def test_primary_translatable_with_package_link(self): + # Create a product that uses translations. + product = self.factory.makeProduct() + series = product.development_focus + product.official_rosetta = True + view = ProductView(product, LaunchpadTestRequest()) + # If development focus series is linked to # a distribution package with translations, # we do not try to show translation statistics # for the package. sourcepackage = self.factory.makeSourcePackage() - sourcepackage.setPackaging(self.series, None) + sourcepackage.setPackaging(series, None) sourcepackage.distroseries.distribution.official_rosetta = True pot = self.factory.makePOTemplate( distroseries=sourcepackage.distroseries, sourcepackagename=sourcepackage.sourcepackagename) - self.assertEquals(None, self.view.primary_translatable) + self.assertEquals(None, view.primary_translatable) + + def test_untranslatable_series(self): + # Create a product that uses translations. + product = self.factory.makeProduct() + series_trunk = product.development_focus + product.official_rosetta = True + view = ProductView(product, LaunchpadTestRequest()) + + # New series are added, one for each type of status + series_experimental = self.factory.makeProductSeries( + product=product, name='evo-experimental') + series_experimental.status = SeriesStatus.EXPERIMENTAL + + series_development = self.factory.makeProductSeries( + product=product, name='evo-development') + series_development.status = SeriesStatus.DEVELOPMENT + + series_frozen = self.factory.makeProductSeries( + product=product, name='evo-frozen') + series_frozen.status = SeriesStatus.FROZEN + + series_current = self.factory.makeProductSeries( + product=product, name='evo-current') + series_current.status = SeriesStatus.CURRENT + + series_supported = self.factory.makeProductSeries( + product=product, name='evo-supported') + series_supported.status = SeriesStatus.SUPPORTED + + series_obsolete = self.factory.makeProductSeries( + product=product, name='evo-obsolete') + series_obsolete.status = SeriesStatus.OBSOLETE + + series_future = self.factory.makeProductSeries( + product=product, name='evo-future') + series_future.status = SeriesStatus.FUTURE + + # 'untranslatable_series' is a cached property, this is why we + # check it after adding all series. + self.assertTrue(series_experimental in view.untranslatable_series) + self.assertTrue(series_development in view.untranslatable_series) + self.assertTrue(series_frozen in view.untranslatable_series) + self.assertTrue(series_current in view.untranslatable_series) + self.assertTrue(series_supported in view.untranslatable_series) + self.assertTrue(series_future in view.untranslatable_series) + + # Obsolete series are not included + self.assertFalse(series_obsolete in view.untranslatable_series) + + # Series are listed in alphabetical order, 'evo-current' + # is firsts, while 'trunk' is last. + self.assertTrue( + series_current == view.untranslatable_series[0]) + self.assertTrue( + series_trunk == view.untranslatable_series[-1]) + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__) - === modified file 'lib/lp/translations/stories/productseries/xx-productseries-translations.txt' --- lib/lp/translations/stories/productseries/xx-productseries-translations.txt 2010-01-28 11:40:00 +0000 +++ lib/lp/translations/stories/productseries/xx-productseries-translations.txt 2010-01-28 12:03:44 +0000 @@ -270,89 +270,58 @@ Launchpad currently recommends translating 1.6. -Setting up translations for a series +Setting up translations for series ------------------------------------ - -When visiting product translations main page, users sees status for -current series configured for translations. -Beside the "Set up translations for a series" section, they will find -links to other series to be configured for translations. -Obsolete series are not presented in the list + +When visiting product translations main page, project developers sees +status for current series configured for translations. +Beside the "All translatable series" section, they will find the +"Set up translations for a series" section with links to other series +that can be configured for translations. When projects have only one active series, and it is already configured, project admin does not see the link for configuring other branches. - + >>> admin_browser.open( ... 'http://translations.launchpad.dev/evolution') >>> untranslatable = find_tag_by_id( ... admin_browser.contents, 'portlet-untranslatable-branches') >>> untranslatable is None True - -New series are added, one for each type of status, to have a full test -coverage. - + +A new series is added. + >>> from lp.registry.model.product import Product >>> from lp.registry.interfaces.series import SeriesStatus >>> login('