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

Proposed by Henning Eggers
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 11810
Proposed branch: lp:~henninge/launchpad/devel-productseries-views-tests
Merge into: lp:launchpad
Diff against target: 386 lines (+175/-120)
2 files modified
lib/lp/testing/factory.py (+26/-9)
lib/lp/translations/browser/tests/test_productserieslanguage_views.py (+149/-111)
To merge this branch: bzr merge lp:~henninge/launchpad/devel-productseries-views-tests
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+39437@code.launchpad.net

Commit message

Improved tests for translations.ProductSeriesView and ProductSeriesLanguagesView. LaunchpadObjectFactory does not require a language code for POFiles and such anymore.

Description of the change

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

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Much better. Thanks for the cleanup!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-10-27 14:25:19 +0000
+++ lib/lp/testing/factory.py 2010-10-27 21:28:59 +0000
@@ -729,8 +729,8 @@
729 PollSecrecy.SECRET, allowspoilt=True,729 PollSecrecy.SECRET, allowspoilt=True,
730 poll_type=poll_type)730 poll_type=poll_type)
731731
732 def makeTranslationGroup(732 def makeTranslationGroup(self, owner=None, name=None, title=None,
733 self, owner=None, name=None, title=None, summary=None, url=None):733 summary=None, url=None):
734 """Create a new, arbitrary `TranslationGroup`."""734 """Create a new, arbitrary `TranslationGroup`."""
735 if owner is None:735 if owner is None:
736 owner = self.makePerson()736 owner = self.makePerson()
@@ -743,10 +743,21 @@
743 return getUtility(ITranslationGroupSet).new(743 return getUtility(ITranslationGroupSet).new(
744 name, title, summary, url, owner)744 name, title, summary, url, owner)
745745
746 def makeTranslator(746 def makeTranslator(self, language_code=None, group=None, person=None,
747 self, language_code, group=None, person=None, license=True):747 license=True, language=None):
748 """Create a new, arbitrary `Translator`."""748 """Create a new, arbitrary `Translator`."""
749 language = getUtility(ILanguageSet).getLanguageByCode(language_code)749 assert language_code is None or language is None, (
750 "Please specifiy only one of language_code and language.")
751 if language_code is None:
752 if language is None:
753 language = self.makeLanguage()
754 language_code = language.code
755 else:
756 language = getUtility(ILanguageSet).getLanguageByCode(
757 language_code)
758 if language is None:
759 language = self.makeLanguage(language_code=language_code)
760
750 if group is None:761 if group is None:
751 group = self.makeTranslationGroup()762 group = self.makeTranslationGroup()
752 if person is None:763 if person is None:
@@ -755,8 +766,8 @@
755 tx_person.translations_relicensing_agreement = license766 tx_person.translations_relicensing_agreement = license
756 return getUtility(ITranslatorSet).new(group, language, person)767 return getUtility(ITranslatorSet).new(group, language, person)
757768
758 def makeMilestone(769 def makeMilestone(self, product=None, distribution=None,
759 self, product=None, distribution=None, productseries=None, name=None):770 productseries=None, name=None):
760 if product is None and distribution is None and productseries is None:771 if product is None and distribution is None and productseries is None:
761 product = self.makeProduct()772 product = self.makeProduct()
762 if distribution is None:773 if distribution is None:
@@ -2280,9 +2291,15 @@
2280 self.makePOFile(language_code, template, template.owner)2291 self.makePOFile(language_code, template, template.owner)
2281 return template2292 return template
22822293
2283 def makePOFile(self, language_code, potemplate=None, owner=None,2294 def makePOFile(self, language_code=None, potemplate=None, owner=None,
2284 create_sharing=False, variant=None):2295 create_sharing=False, language=None, variant=None):
2285 """Make a new translation file."""2296 """Make a new translation file."""
2297 assert language_code is None or language is None, (
2298 "Please specifiy only one of language_code and language.")
2299 if language_code is None:
2300 if language is None:
2301 language = self.makeLanguage()
2302 language_code = language.code
2286 if potemplate is None:2303 if potemplate is None:
2287 potemplate = self.makePOTemplate(owner=owner)2304 potemplate = self.makePOTemplate(owner=owner)
2288 pofile = potemplate.newPOFile(language_code,2305 pofile = potemplate.newPOFile(language_code,
22892306
=== 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 21:28:59 +0000
@@ -3,164 +3,202 @@
33
4__metaclass__ = type4__metaclass__ = type
55
6from zope.component import getUtility
7
8from canonical.launchpad.webapp.servers import LaunchpadTestRequest6from canonical.launchpad.webapp.servers import LaunchpadTestRequest
9from canonical.testing.layers import LaunchpadZopelessLayer7from canonical.testing.layers import LaunchpadZopelessLayer
10from lp.services.worlddata.interfaces.language import ILanguageSet
11from lp.testing import (8from lp.testing import (
12 login_person,9 login_person,
13 TestCaseWithFactory,10 TestCaseWithFactory,
14 )11 )
15from lp.translations.browser.productseries import ProductSeriesView12from lp.translations.browser.productseries import ProductSeriesView
16from lp.translations.browser.serieslanguage import ProductSeriesLanguageView13from lp.translations.browser.serieslanguage import ProductSeriesLanguageView
17from lp.translations.interfaces.translator import ITranslatorSet14
1815
1916class TestProductSeriesView(TestCaseWithFactory):
20class TestProductSeries(TestCaseWithFactory):
21 """Test ProductSeries view in translations facet."""17 """Test ProductSeries view in translations facet."""
2218
23 layer = LaunchpadZopelessLayer19 layer = LaunchpadZopelessLayer
2420
25 def setUp(self):21 def setUp(self):
26 # Create a productseries that uses translations.22 # Create a productseries that uses translations.
27 TestCaseWithFactory.setUp(self)23 super(TestProductSeriesView, self).setUp()
28 self.productseries = self.factory.makeProductSeries()24 self.productseries = self.factory.makeProductSeries()
29 self.productseries.product.official_rosetta = True25 self.productseries.product.official_rosetta = True
30 self.view = ProductSeriesView(self.productseries,26 self.product = self.productseries.product
31 LaunchpadTestRequest())27
3228 def _createView(self):
33 def test_single_potemplate(self):29 return ProductSeriesView(self.productseries, LaunchpadTestRequest())
34 # Make sure that `single_potemplate` is True only when30
35 # there is exactly one POTemplate for the ProductSeries.31 def test_single_potemplate_no_template(self):
3632 view = self._createView()
37 self.assertFalse(self.view.single_potemplate)33 self.assertFalse(view.single_potemplate)
3834
39 potemplate1 = self.factory.makePOTemplate(35 def test_single_potemplate_one_template(self):
40 productseries=self.productseries)36 self.factory.makePOTemplate(productseries=self.productseries)
4137 view = self._createView()
42 # self.view may cache the old single_potemplate value, so create38 self.assertTrue(view.single_potemplate)
43 # a fresh view now that the underlying data has changed.39
44 fresh_view = ProductSeriesView(40 def test_single_potemplate_multiple_templates(self):
45 self.productseries, LaunchpadTestRequest())41 self.factory.makePOTemplate(productseries=self.productseries)
46 self.assertTrue(fresh_view.single_potemplate)42 self.factory.makePOTemplate(productseries=self.productseries)
4743 view = self._createView()
48 potemplate2 = self.factory.makePOTemplate(44 self.assertFalse(view.single_potemplate)
49 productseries=self.productseries)45
50 fresh_view = ProductSeriesView(46 def test_has_translation_documentation_no_group(self):
51 self.productseries, LaunchpadTestRequest())47 # Without a translation group, there is no documentation either.
52 self.assertFalse(fresh_view.single_potemplate)48 view = self._createView()
5349 self.assertFalse(view.has_translation_documentation)
54 def test_has_translation_documentation(self):50
55 self.assertFalse(self.view.has_translation_documentation)51 def test_has_translation_documentation_group_without_url(self):
56
57 # Adding a translation group with no documentation keeps52 # Adding a translation group with no documentation keeps
58 # `has_translation_documentation` at False.53 # `has_translation_documentation` at False.
59 group = self.factory.makeTranslationGroup(54 self.product.translationgroup = self.factory.makeTranslationGroup(
60 self.productseries.product.owner, url=None)55 self.productseries.product.owner, url=None)
61 self.productseries.product.translationgroup = group56 view = self._createView()
62 self.assertFalse(self.view.has_translation_documentation)57 self.assertFalse(view.has_translation_documentation)
6358
64 # When there is documentation URL, `has_translation_documentation`59 def test_has_translation_documentation_group_with_url(self):
65 # is True.60 # After adding a translation group with a documentation URL lets
66 group.translation_guide_url = u'http://something'61 # `has_translation_documentation` be True.
67 self.assertTrue(self.view.has_translation_documentation)62 self.product.translationgroup = self.factory.makeTranslationGroup(
6863 self.productseries.product.owner, url=u'http://something')
69 def test_productserieslanguages(self):64 view = self._createView()
70 # With no POTemplates, it returns None.65 self.assertTrue(view.has_translation_documentation)
71 self.assertEquals(self.view.productserieslanguages,66
72 None)67 def test_productserieslanguages_no_template(self):
7368 # With no POTemplates, no languages can be seen, either.
74 # Adding a single POTemplate, but no actual translations69 view = self._createView()
75 # makes `productserieslanguages` return an empty list instead.70 self.assertEquals(None, view.productserieslanguages)
71
72 def _getProductserieslanguages(self, view):
73 return [psl.language for psl in view.productserieslanguages]
74
75 def test_productserieslanguages_without_pofile(self):
76 # With a single POTemplate, but no actual translations, the list
77 # of languages is empty.
78 self.factory.makePOTemplate(productseries=self.productseries)
79 view = self._createView()
80 self.assertEquals([], self._getProductserieslanguages(view))
81
82 def test_productserieslanguages_with_pofile(self):
83 # The `productserieslanguages` properperty has a list of the
84 # languages of the po files for the templates in this seris.
76 potemplate = self.factory.makePOTemplate(85 potemplate = self.factory.makePOTemplate(
77 productseries=self.productseries)86 productseries=self.productseries)
78 self.assertEquals(self.view.productserieslanguages,87 pofile = self.factory.makePOFile(potemplate=potemplate)
79 [])88 view = self._createView()
8089 self.assertEquals(
81 # Adding a translation, adds that language to the list.90 [pofile.language], self._getProductserieslanguages(view))
82 pofile = self.factory.makePOFile('sr', potemplate)91
83 self.assertEquals(len(self.view.productserieslanguages),92 def _makePersonWithLanguage(self):
84 1)
85 self.assertEquals(self.view.productserieslanguages[0].language,
86 pofile.language)
87
88 # If a user with another preferred languages looks at
89 # the list, that language is combined with existing one.
90 user = self.factory.makePerson()93 user = self.factory.makePerson()
91 spanish = getUtility(ILanguageSet).getLanguageByCode('es')94 language = self.factory.makeLanguage()
92 user.addLanguage(spanish)95 user.addLanguage(language)
93 self.assertEquals(len(user.languages), 1)96 return user, language
9497
95 login_person(user)98 def test_productserieslanguages_preferred_language_without_pofile(self):
96 view = ProductSeriesView(self.productseries, LaunchpadTestRequest())99 # If the user has a preferred language, that language always in
100 # the list.
101 self.factory.makePOTemplate(
102 productseries=self.productseries)
103 user, language = self._makePersonWithLanguage()
104 login_person(user)
105 view = self._createView()
106 self.assertEquals([language], self._getProductserieslanguages(view))
107
108 def test_productserieslanguages_preferred_language_with_pofile(self):
109 # If the user has a preferred language, that language always in
110 # the list.
111 potemplate = self.factory.makePOTemplate(
112 productseries=self.productseries)
113 pofile = self.factory.makePOFile(potemplate=potemplate)
114 user, language = self._makePersonWithLanguage()
115 login_person(user)
116 view = self._createView()
117 self.assertContentEqual(
118 [pofile.language, language],
119 self._getProductserieslanguages(view))
120
121 def test_productserieslanguages_ordered_by_englishname(self):
97 # Returned languages are ordered by their name in English.122 # Returned languages are ordered by their name in English.
123 language1 = self.factory.makeLanguage(
124 language_code='lang-aa', name='Zz')
125 language2 = self.factory.makeLanguage(
126 language_code='lang-zz', name='Aa')
127 potemplate = self.factory.makePOTemplate(
128 productseries=self.productseries)
129 self.factory.makePOFile(language=language1, potemplate=potemplate)
130 self.factory.makePOFile(language=language2, potemplate=potemplate)
131 view = self._createView()
98 self.assertEquals(132 self.assertEquals(
99 [psl.language.englishname for psl in view.productserieslanguages],133 [language2, language1], self._getProductserieslanguages(view))
100 [u'Serbian', u'Spanish'])
101134
102 def test_productserieslanguages_english(self):135 def test_productserieslanguages_english(self):
103 # Even if there's an English POFile, it's not listed136 # English is not listed among translated languages, even if there's
104 # among translated languages.137 # an English POFile
105 potemplate = self.factory.makePOTemplate(138 potemplate = self.factory.makePOTemplate(
106 productseries=self.productseries)139 productseries=self.productseries)
107 pofile = self.factory.makePOFile('en', potemplate)140 self.factory.makePOFile('en', potemplate)
108 self.assertEquals(self.view.productserieslanguages,141 view = self._createView()
109 [])142 self.assertEquals([], self._getProductserieslanguages(view))
110143
111 # It's not shown even with more than one POTemplate144 # It's not shown even with more than one POTemplate
112 # (different code paths).145 # (different code paths).
113 potemplate2 = self.factory.makePOTemplate(146 self.factory.makePOTemplate(productseries=self.productseries)
114 productseries=self.productseries)147 self.assertEquals([], self._getProductserieslanguages(view))
115 self.assertEquals(self.view.productserieslanguages,148
116 [])149
117150class TestProductSeriesLanguageView(TestCaseWithFactory):
118
119class TestProductSeriesLanguage(TestCaseWithFactory):
120 """Test ProductSeriesLanguage view."""151 """Test ProductSeriesLanguage view."""
121152
122 layer = LaunchpadZopelessLayer153 layer = LaunchpadZopelessLayer
123154
124 def setUp(self):155 def setUp(self):
125 # Create a productseries that uses translations.156 # Create a productseries that uses translations.
126 TestCaseWithFactory.setUp(self)157 super(TestProductSeriesLanguageView, self).setUp()
127 self.productseries = self.factory.makeProductSeries()158 self.productseries = self.factory.makeProductSeries()
128 self.productseries.product.official_rosetta = True159 self.productseries.product.official_rosetta = True
129 self.language = getUtility(ILanguageSet).getLanguageByCode('sr')160 self.language = self.factory.makeLanguage()
130 potemplate = self.factory.makePOTemplate(161 potemplate = self.factory.makePOTemplate(
131 productseries=self.productseries)162 productseries=self.productseries)
132 pofile = self.factory.makePOFile('sr', potemplate)163 self.factory.makePOFile(language=self.language, potemplate=potemplate)
133 self.psl = self.productseries.productserieslanguages[0]164 self.psl = self.productseries.productserieslanguages[0]
134 self.view = ProductSeriesLanguageView(165
135 self.psl, LaunchpadTestRequest())166 def _createView(self):
136167 view = ProductSeriesLanguageView(self.psl, LaunchpadTestRequest())
137 def test_empty_view(self):168 view.initialize()
138 self.assertEquals(self.view.translation_group, None)169 return view
139 self.assertEquals(self.view.translation_team, None)170
140 self.assertEquals(self.view.context, self.psl)171 def test_translation_group_no_group(self):
172 view = self._createView()
173 self.assertEquals(None, view.translation_group)
174
175 def test_translation_team_no_group_no_team(self):
176 view = self._createView()
177 self.assertEquals(None, view.translation_team)
178
179 def _makeTranslationGroup(self):
180 group = self.factory.makeTranslationGroup(
181 self.productseries.product.owner, url=None)
182 self.productseries.product.translationgroup = group
183 return group
141184
142 def test_translation_group(self):185 def test_translation_group(self):
143 group = self.factory.makeTranslationGroup(186 group = self._makeTranslationGroup()
144 self.productseries.product.owner, url=None)187 view = self._createView()
145 self.productseries.product.translationgroup = group188 self.assertEquals(group, view.translation_group)
146 self.view.initialize()
147 self.assertEquals(self.view.translation_group, group)
148189
149 def test_translation_team(self):190 def test_translation_team_no_translator(self):
150 # Just having a group doesn't mean there's a translation191 # Just having a group doesn't mean there's a translation
151 # team as well.192 # team as well.
152 group = self.factory.makeTranslationGroup(193 self._makeTranslationGroup()
153 self.productseries.product.owner, url=None)194 view = self._createView()
154 self.productseries.product.translationgroup = group195 self.assertEquals(None, view.translation_team)
155 self.assertEquals(self.view.translation_team, None)
156196
197 def test_translation_team(self):
157 # Setting a translator for this languages makes it198 # Setting a translator for this languages makes it
158 # appear as the translation_team.199 # appear as the translation_team.
159 team = self.factory.makeTeam()200 group = self._makeTranslationGroup()
160 translator = getUtility(ITranslatorSet).new(201 translator = self.factory.makeTranslator(
161 group, self.language, team)202 group=group, language=self.language)
162 # Recreate the view because we are using a cached property.203 view = self._createView()
163 self.view = ProductSeriesLanguageView(204 self.assertEquals(translator, view.translation_team)
164 self.psl, LaunchpadTestRequest())
165 self.view.initialize()
166 self.assertEquals(self.view.translation_team, translator)