← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~henninge/launchpad/devel-productseries-views-tests into lp:launchpad/devel

 

Henning Eggers has proposed merging lp:~henninge/launchpad/devel-productseries-views-tests into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


In preparation for fixing bug 638920 I looked for a place for my tests. This will be in test_productserieslanguage_views.py. The tests in that file seemed to have been converted from a doc test and could use a lot of improvement. I did those and since they are unrelated to the bug I submit them here separately.

I fixed the following things:
- Broke tests down into smaller methods.
- The view is now created only after the context has been fully setUp. It's not good to rely on properties not being cached.
- Do not depend on sample data (Languages).

No lint. No qa. A full test run will show if I broke the factory.

bin/test -vvcm lp.translations.browser.tests.test_productserieslanguage_views


-- 
https://code.launchpad.net/~henninge/launchpad/devel-productseries-views-tests/+merge/39437
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~henninge/launchpad/devel-productseries-views-tests into lp:launchpad/devel.
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2010-10-27 04:10:45 +0000
+++ lib/lp/testing/factory.py	2010-10-27 11:56:34 +0000
@@ -729,8 +729,8 @@
             PollSecrecy.SECRET, allowspoilt=True,
             poll_type=poll_type)
 
-    def makeTranslationGroup(
-        self, owner=None, name=None, title=None, summary=None, url=None):
+    def makeTranslationGroup(self, owner=None, name=None, title=None,
+                             summary=None, url=None):
         """Create a new, arbitrary `TranslationGroup`."""
         if owner is None:
             owner = self.makePerson()
@@ -743,10 +743,21 @@
         return getUtility(ITranslationGroupSet).new(
             name, title, summary, url, owner)
 
-    def makeTranslator(
-        self, language_code, group=None, person=None, license=True):
+    def makeTranslator(self, language_code=None, group=None, person=None,
+                       license=True, language=None):
         """Create a new, arbitrary `Translator`."""
-        language = getUtility(ILanguageSet).getLanguageByCode(language_code)
+        assert language_code is None or language is None, (
+            "Please specifiy only one of language_code and language.")
+        if language_code is None:
+            if language is None:
+                language = self.makeLanguage()
+            language_code = language.code
+        else:
+            language = getUtility(ILanguageSet).getLanguageByCode(
+                language_code)
+            if language is None:
+                language = self.makeLanguage(language_code=language_code)
+
         if group is None:
             group = self.makeTranslationGroup()
         if person is None:
@@ -755,8 +766,8 @@
         tx_person.translations_relicensing_agreement = license
         return getUtility(ITranslatorSet).new(group, language, person)
 
-    def makeMilestone(
-        self, product=None, distribution=None, productseries=None, name=None):
+    def makeMilestone(self, product=None, distribution=None,
+                      productseries=None, name=None):
         if product is None and distribution is None and productseries is None:
             product = self.makeProduct()
         if distribution is None:
@@ -2274,9 +2285,15 @@
             self.makePOFile(language_code, template, template.owner)
         return template
 
-    def makePOFile(self, language_code, potemplate=None, owner=None,
-                   create_sharing=False, variant=None):
+    def makePOFile(self, language_code=None, potemplate=None, owner=None,
+                   create_sharing=False, language=None, variant=None):
         """Make a new translation file."""
+        assert language_code is None or language is None, (
+            "Please specifiy only one of language_code and language.")
+        if language_code is None:
+            if language is None:
+                language = self.makeLanguage()
+            language_code = language.code
         if potemplate is None:
             potemplate = self.makePOTemplate(owner=owner)
         pofile = potemplate.newPOFile(language_code,

=== modified file 'lib/lp/translations/browser/tests/test_productserieslanguage_views.py'
--- lib/lp/translations/browser/tests/test_productserieslanguage_views.py	2010-10-05 00:08:16 +0000
+++ lib/lp/translations/browser/tests/test_productserieslanguage_views.py	2010-10-27 11:56:34 +0000
@@ -3,164 +3,202 @@
 
 __metaclass__ = type
 
-from zope.component import getUtility
-
 from canonical.launchpad.webapp.servers import LaunchpadTestRequest
 from canonical.testing.layers import LaunchpadZopelessLayer
-from lp.services.worlddata.interfaces.language import ILanguageSet
 from lp.testing import (
     login_person,
     TestCaseWithFactory,
     )
 from lp.translations.browser.productseries import ProductSeriesView
 from lp.translations.browser.serieslanguage import ProductSeriesLanguageView
-from lp.translations.interfaces.translator import ITranslatorSet
-
-
-class TestProductSeries(TestCaseWithFactory):
+
+
+class TestProductSeriesView(TestCaseWithFactory):
     """Test ProductSeries view in translations facet."""
 
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
         # Create a productseries that uses translations.
-        TestCaseWithFactory.setUp(self)
+        super(TestProductSeriesView, self).setUp()
         self.productseries = self.factory.makeProductSeries()
         self.productseries.product.official_rosetta = True
-        self.view = ProductSeriesView(self.productseries,
-                                      LaunchpadTestRequest())
-
-    def test_single_potemplate(self):
-        # Make sure that `single_potemplate` is True only when
-        # there is exactly one POTemplate for the ProductSeries.
-
-        self.assertFalse(self.view.single_potemplate)
-
-        potemplate1 = self.factory.makePOTemplate(
-            productseries=self.productseries)
-
-        # self.view may cache the old single_potemplate value, so create
-        # a fresh view now that the underlying data has changed.
-        fresh_view = ProductSeriesView(
-            self.productseries, LaunchpadTestRequest())
-        self.assertTrue(fresh_view.single_potemplate)
-
-        potemplate2 = self.factory.makePOTemplate(
-            productseries=self.productseries)
-        fresh_view = ProductSeriesView(
-            self.productseries, LaunchpadTestRequest())
-        self.assertFalse(fresh_view.single_potemplate)
-
-    def test_has_translation_documentation(self):
-        self.assertFalse(self.view.has_translation_documentation)
-
+        self.product = self.productseries.product
+
+    def _createView(self):
+        return ProductSeriesView(self.productseries, LaunchpadTestRequest())
+
+    def test_single_potemplate_no_template(self):
+        view = self._createView()
+        self.assertFalse(view.single_potemplate)
+
+    def test_single_potemplate_one_template(self):
+        self.factory.makePOTemplate(productseries=self.productseries)
+        view = self._createView()
+        self.assertTrue(view.single_potemplate)
+
+    def test_single_potemplate_multiple_templates(self):
+        self.factory.makePOTemplate(productseries=self.productseries)
+        self.factory.makePOTemplate(productseries=self.productseries)
+        view = self._createView()
+        self.assertFalse(view.single_potemplate)
+
+    def test_has_translation_documentation_no_group(self):
+        # Without a translation group, there is no documentation either.
+        view = self._createView()
+        self.assertFalse(view.has_translation_documentation)
+
+    def test_has_translation_documentation_group_without_url(self):
         # Adding a translation group with no documentation keeps
         # `has_translation_documentation` at False.
-        group = self.factory.makeTranslationGroup(
+        self.product.translationgroup = self.factory.makeTranslationGroup(
             self.productseries.product.owner, url=None)
-        self.productseries.product.translationgroup = group
-        self.assertFalse(self.view.has_translation_documentation)
-
-        # When there is documentation URL, `has_translation_documentation`
-        # is True.
-        group.translation_guide_url = u'http://something'
-        self.assertTrue(self.view.has_translation_documentation)
-
-    def test_productserieslanguages(self):
-        # With no POTemplates, it returns None.
-        self.assertEquals(self.view.productserieslanguages,
-                          None)
-
-        # Adding a single POTemplate, but no actual translations
-        # makes `productserieslanguages` return an empty list instead.
+        view = self._createView()
+        self.assertFalse(view.has_translation_documentation)
+
+    def test_has_translation_documentation_group_with_url(self):
+        # After adding a translation group with a documentation URL lets
+        # `has_translation_documentation` be True.
+        self.product.translationgroup = self.factory.makeTranslationGroup(
+            self.productseries.product.owner, url=u'http://something')
+        view = self._createView()
+        self.assertTrue(view.has_translation_documentation)
+
+    def test_productserieslanguages_no_template(self):
+        # With no POTemplates, no languages can be seen, either.
+        view = self._createView()
+        self.assertEquals(None, view.productserieslanguages)
+
+    def _getProductserieslanguages(self, view):
+        return [psl.language for psl in view.productserieslanguages]
+
+    def test_productserieslanguages_without_pofile(self):
+        # With a single POTemplate, but no actual translations, the list
+        # of languages is empty.
+        self.factory.makePOTemplate(productseries=self.productseries)
+        view = self._createView()
+        self.assertEquals([], self._getProductserieslanguages(view))
+
+    def test_productserieslanguages_with_pofile(self):
+        # The `productserieslanguages` properperty has a list of the
+        # languages of the po files for the templates in this seris.
         potemplate = self.factory.makePOTemplate(
             productseries=self.productseries)
-        self.assertEquals(self.view.productserieslanguages,
-                          [])
-
-        # Adding a translation, adds that language to the list.
-        pofile = self.factory.makePOFile('sr', potemplate)
-        self.assertEquals(len(self.view.productserieslanguages),
-                          1)
-        self.assertEquals(self.view.productserieslanguages[0].language,
-                          pofile.language)
-
-        # If a user with another preferred languages looks at
-        # the list, that language is combined with existing one.
+        pofile = self.factory.makePOFile(potemplate=potemplate)
+        view = self._createView()
+        self.assertEquals(
+            [pofile.language], self._getProductserieslanguages(view))
+
+    def _makePersonWithLanguage(self):
         user = self.factory.makePerson()
-        spanish = getUtility(ILanguageSet).getLanguageByCode('es')
-        user.addLanguage(spanish)
-        self.assertEquals(len(user.languages), 1)
-
-        login_person(user)
-        view = ProductSeriesView(self.productseries, LaunchpadTestRequest())
+        language = self.factory.makeLanguage()
+        user.addLanguage(language)
+        return user, language
+
+    def test_productserieslanguages_preferred_language_without_pofile(self):
+        # If the user has a preferred language, that language always in
+        # the list.
+        self.factory.makePOTemplate(
+            productseries=self.productseries)
+        user, language = self._makePersonWithLanguage()
+        login_person(user)
+        view = self._createView()
+        self.assertEquals([language], self._getProductserieslanguages(view))
+
+    def test_productserieslanguages_preferred_language_with_pofile(self):
+        # If the user has a preferred language, that language always in
+        # the list.
+        potemplate = self.factory.makePOTemplate(
+            productseries=self.productseries)
+        pofile = self.factory.makePOFile(potemplate=potemplate)
+        user, language = self._makePersonWithLanguage()
+        login_person(user)
+        view = self._createView()
+        self.assertContentEqual(
+            [pofile.language, language],
+            self._getProductserieslanguages(view))
+
+    def test_productserieslanguages_ordered_by_englishname(self):
         # Returned languages are ordered by their name in English.
+        language1 = self.factory.makeLanguage(
+            language_code='lang-aa', name='Zz')
+        language2 = self.factory.makeLanguage(
+            language_code='lang-zz', name='Aa')
+        potemplate = self.factory.makePOTemplate(
+            productseries=self.productseries)
+        self.factory.makePOFile(language=language1, potemplate=potemplate)
+        self.factory.makePOFile(language=language2, potemplate=potemplate)
+        view = self._createView()
         self.assertEquals(
-            [psl.language.englishname for psl in view.productserieslanguages],
-            [u'Serbian', u'Spanish'])
+            [language2, language1], self._getProductserieslanguages(view))
 
     def test_productserieslanguages_english(self):
-        # Even if there's an English POFile, it's not listed
-        # among translated languages.
+        # English is not listed among translated languages, even if there's
+        # an English POFile
         potemplate = self.factory.makePOTemplate(
             productseries=self.productseries)
-        pofile = self.factory.makePOFile('en', potemplate)
-        self.assertEquals(self.view.productserieslanguages,
-                          [])
+        self.factory.makePOFile('en', potemplate)
+        view = self._createView()
+        self.assertEquals([], self._getProductserieslanguages(view))
 
         # It's not shown even with more than one POTemplate
         # (different code paths).
-        potemplate2 = self.factory.makePOTemplate(
-            productseries=self.productseries)
-        self.assertEquals(self.view.productserieslanguages,
-                          [])
-
-
-class TestProductSeriesLanguage(TestCaseWithFactory):
+        self.factory.makePOTemplate(productseries=self.productseries)
+        self.assertEquals([], self._getProductserieslanguages(view))
+
+
+class TestProductSeriesLanguageView(TestCaseWithFactory):
     """Test ProductSeriesLanguage view."""
 
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
         # Create a productseries that uses translations.
-        TestCaseWithFactory.setUp(self)
+        super(TestProductSeriesLanguageView, self).setUp()
         self.productseries = self.factory.makeProductSeries()
         self.productseries.product.official_rosetta = True
-        self.language = getUtility(ILanguageSet).getLanguageByCode('sr')
+        self.language = self.factory.makeLanguage()
         potemplate = self.factory.makePOTemplate(
             productseries=self.productseries)
-        pofile = self.factory.makePOFile('sr', potemplate)
+        self.factory.makePOFile(language=self.language, potemplate=potemplate)
         self.psl = self.productseries.productserieslanguages[0]
-        self.view = ProductSeriesLanguageView(
-            self.psl, LaunchpadTestRequest())
-
-    def test_empty_view(self):
-        self.assertEquals(self.view.translation_group, None)
-        self.assertEquals(self.view.translation_team, None)
-        self.assertEquals(self.view.context, self.psl)
+
+    def _createView(self):
+        view = ProductSeriesLanguageView(self.psl, LaunchpadTestRequest())
+        view.initialize()
+        return view
+
+    def test_translation_group_no_group(self):
+        view = self._createView()
+        self.assertEquals(None, view.translation_group)
+
+    def test_translation_team_no_group_no_team(self):
+        view = self._createView()
+        self.assertEquals(None, view.translation_team)
+
+    def _makeTranslationGroup(self):
+        group = self.factory.makeTranslationGroup(
+            self.productseries.product.owner, url=None)
+        self.productseries.product.translationgroup = group
+        return group
 
     def test_translation_group(self):
-        group = self.factory.makeTranslationGroup(
-            self.productseries.product.owner, url=None)
-        self.productseries.product.translationgroup = group
-        self.view.initialize()
-        self.assertEquals(self.view.translation_group, group)
+        group = self._makeTranslationGroup()
+        view = self._createView()
+        self.assertEquals(group, view.translation_group)
 
-    def test_translation_team(self):
+    def test_translation_team_no_translator(self):
         # Just having a group doesn't mean there's a translation
         # team as well.
-        group = self.factory.makeTranslationGroup(
-            self.productseries.product.owner, url=None)
-        self.productseries.product.translationgroup = group
-        self.assertEquals(self.view.translation_team, None)
+        self._makeTranslationGroup()
+        view = self._createView()
+        self.assertEquals(None, view.translation_team)
 
+    def test_translation_team(self):
         # Setting a translator for this languages makes it
         # appear as the translation_team.
-        team = self.factory.makeTeam()
-        translator = getUtility(ITranslatorSet).new(
-            group, self.language, team)
-        # Recreate the view because we are using a cached property.
-        self.view = ProductSeriesLanguageView(
-            self.psl, LaunchpadTestRequest())
-        self.view.initialize()
-        self.assertEquals(self.view.translation_team, translator)
+        group = self._makeTranslationGroup()
+        translator = self.factory.makeTranslator(
+            group=group, language=self.language)
+        view = self._createView()
+        self.assertEquals(translator, view.translation_team)