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
1=== modified file 'lib/lp/testing/factory.py'
2--- lib/lp/testing/factory.py 2010-10-27 14:25:19 +0000
3+++ lib/lp/testing/factory.py 2010-10-27 21:28:59 +0000
4@@ -729,8 +729,8 @@
5 PollSecrecy.SECRET, allowspoilt=True,
6 poll_type=poll_type)
7
8- def makeTranslationGroup(
9- self, owner=None, name=None, title=None, summary=None, url=None):
10+ def makeTranslationGroup(self, owner=None, name=None, title=None,
11+ summary=None, url=None):
12 """Create a new, arbitrary `TranslationGroup`."""
13 if owner is None:
14 owner = self.makePerson()
15@@ -743,10 +743,21 @@
16 return getUtility(ITranslationGroupSet).new(
17 name, title, summary, url, owner)
18
19- def makeTranslator(
20- self, language_code, group=None, person=None, license=True):
21+ def makeTranslator(self, language_code=None, group=None, person=None,
22+ license=True, language=None):
23 """Create a new, arbitrary `Translator`."""
24- language = getUtility(ILanguageSet).getLanguageByCode(language_code)
25+ assert language_code is None or language is None, (
26+ "Please specifiy only one of language_code and language.")
27+ if language_code is None:
28+ if language is None:
29+ language = self.makeLanguage()
30+ language_code = language.code
31+ else:
32+ language = getUtility(ILanguageSet).getLanguageByCode(
33+ language_code)
34+ if language is None:
35+ language = self.makeLanguage(language_code=language_code)
36+
37 if group is None:
38 group = self.makeTranslationGroup()
39 if person is None:
40@@ -755,8 +766,8 @@
41 tx_person.translations_relicensing_agreement = license
42 return getUtility(ITranslatorSet).new(group, language, person)
43
44- def makeMilestone(
45- self, product=None, distribution=None, productseries=None, name=None):
46+ def makeMilestone(self, product=None, distribution=None,
47+ productseries=None, name=None):
48 if product is None and distribution is None and productseries is None:
49 product = self.makeProduct()
50 if distribution is None:
51@@ -2280,9 +2291,15 @@
52 self.makePOFile(language_code, template, template.owner)
53 return template
54
55- def makePOFile(self, language_code, potemplate=None, owner=None,
56- create_sharing=False, variant=None):
57+ def makePOFile(self, language_code=None, potemplate=None, owner=None,
58+ create_sharing=False, language=None, variant=None):
59 """Make a new translation file."""
60+ assert language_code is None or language is None, (
61+ "Please specifiy only one of language_code and language.")
62+ if language_code is None:
63+ if language is None:
64+ language = self.makeLanguage()
65+ language_code = language.code
66 if potemplate is None:
67 potemplate = self.makePOTemplate(owner=owner)
68 pofile = potemplate.newPOFile(language_code,
69
70=== modified file 'lib/lp/translations/browser/tests/test_productserieslanguage_views.py'
71--- lib/lp/translations/browser/tests/test_productserieslanguage_views.py 2010-10-05 00:08:16 +0000
72+++ lib/lp/translations/browser/tests/test_productserieslanguage_views.py 2010-10-27 21:28:59 +0000
73@@ -3,164 +3,202 @@
74
75 __metaclass__ = type
76
77-from zope.component import getUtility
78-
79 from canonical.launchpad.webapp.servers import LaunchpadTestRequest
80 from canonical.testing.layers import LaunchpadZopelessLayer
81-from lp.services.worlddata.interfaces.language import ILanguageSet
82 from lp.testing import (
83 login_person,
84 TestCaseWithFactory,
85 )
86 from lp.translations.browser.productseries import ProductSeriesView
87 from lp.translations.browser.serieslanguage import ProductSeriesLanguageView
88-from lp.translations.interfaces.translator import ITranslatorSet
89-
90-
91-class TestProductSeries(TestCaseWithFactory):
92+
93+
94+class TestProductSeriesView(TestCaseWithFactory):
95 """Test ProductSeries view in translations facet."""
96
97 layer = LaunchpadZopelessLayer
98
99 def setUp(self):
100 # Create a productseries that uses translations.
101- TestCaseWithFactory.setUp(self)
102+ super(TestProductSeriesView, self).setUp()
103 self.productseries = self.factory.makeProductSeries()
104 self.productseries.product.official_rosetta = True
105- self.view = ProductSeriesView(self.productseries,
106- LaunchpadTestRequest())
107-
108- def test_single_potemplate(self):
109- # Make sure that `single_potemplate` is True only when
110- # there is exactly one POTemplate for the ProductSeries.
111-
112- self.assertFalse(self.view.single_potemplate)
113-
114- potemplate1 = self.factory.makePOTemplate(
115- productseries=self.productseries)
116-
117- # self.view may cache the old single_potemplate value, so create
118- # a fresh view now that the underlying data has changed.
119- fresh_view = ProductSeriesView(
120- self.productseries, LaunchpadTestRequest())
121- self.assertTrue(fresh_view.single_potemplate)
122-
123- potemplate2 = self.factory.makePOTemplate(
124- productseries=self.productseries)
125- fresh_view = ProductSeriesView(
126- self.productseries, LaunchpadTestRequest())
127- self.assertFalse(fresh_view.single_potemplate)
128-
129- def test_has_translation_documentation(self):
130- self.assertFalse(self.view.has_translation_documentation)
131-
132+ self.product = self.productseries.product
133+
134+ def _createView(self):
135+ return ProductSeriesView(self.productseries, LaunchpadTestRequest())
136+
137+ def test_single_potemplate_no_template(self):
138+ view = self._createView()
139+ self.assertFalse(view.single_potemplate)
140+
141+ def test_single_potemplate_one_template(self):
142+ self.factory.makePOTemplate(productseries=self.productseries)
143+ view = self._createView()
144+ self.assertTrue(view.single_potemplate)
145+
146+ def test_single_potemplate_multiple_templates(self):
147+ self.factory.makePOTemplate(productseries=self.productseries)
148+ self.factory.makePOTemplate(productseries=self.productseries)
149+ view = self._createView()
150+ self.assertFalse(view.single_potemplate)
151+
152+ def test_has_translation_documentation_no_group(self):
153+ # Without a translation group, there is no documentation either.
154+ view = self._createView()
155+ self.assertFalse(view.has_translation_documentation)
156+
157+ def test_has_translation_documentation_group_without_url(self):
158 # Adding a translation group with no documentation keeps
159 # `has_translation_documentation` at False.
160- group = self.factory.makeTranslationGroup(
161+ self.product.translationgroup = self.factory.makeTranslationGroup(
162 self.productseries.product.owner, url=None)
163- self.productseries.product.translationgroup = group
164- self.assertFalse(self.view.has_translation_documentation)
165-
166- # When there is documentation URL, `has_translation_documentation`
167- # is True.
168- group.translation_guide_url = u'http://something'
169- self.assertTrue(self.view.has_translation_documentation)
170-
171- def test_productserieslanguages(self):
172- # With no POTemplates, it returns None.
173- self.assertEquals(self.view.productserieslanguages,
174- None)
175-
176- # Adding a single POTemplate, but no actual translations
177- # makes `productserieslanguages` return an empty list instead.
178+ view = self._createView()
179+ self.assertFalse(view.has_translation_documentation)
180+
181+ def test_has_translation_documentation_group_with_url(self):
182+ # After adding a translation group with a documentation URL lets
183+ # `has_translation_documentation` be True.
184+ self.product.translationgroup = self.factory.makeTranslationGroup(
185+ self.productseries.product.owner, url=u'http://something')
186+ view = self._createView()
187+ self.assertTrue(view.has_translation_documentation)
188+
189+ def test_productserieslanguages_no_template(self):
190+ # With no POTemplates, no languages can be seen, either.
191+ view = self._createView()
192+ self.assertEquals(None, view.productserieslanguages)
193+
194+ def _getProductserieslanguages(self, view):
195+ return [psl.language for psl in view.productserieslanguages]
196+
197+ def test_productserieslanguages_without_pofile(self):
198+ # With a single POTemplate, but no actual translations, the list
199+ # of languages is empty.
200+ self.factory.makePOTemplate(productseries=self.productseries)
201+ view = self._createView()
202+ self.assertEquals([], self._getProductserieslanguages(view))
203+
204+ def test_productserieslanguages_with_pofile(self):
205+ # The `productserieslanguages` properperty has a list of the
206+ # languages of the po files for the templates in this seris.
207 potemplate = self.factory.makePOTemplate(
208 productseries=self.productseries)
209- self.assertEquals(self.view.productserieslanguages,
210- [])
211-
212- # Adding a translation, adds that language to the list.
213- pofile = self.factory.makePOFile('sr', potemplate)
214- self.assertEquals(len(self.view.productserieslanguages),
215- 1)
216- self.assertEquals(self.view.productserieslanguages[0].language,
217- pofile.language)
218-
219- # If a user with another preferred languages looks at
220- # the list, that language is combined with existing one.
221+ pofile = self.factory.makePOFile(potemplate=potemplate)
222+ view = self._createView()
223+ self.assertEquals(
224+ [pofile.language], self._getProductserieslanguages(view))
225+
226+ def _makePersonWithLanguage(self):
227 user = self.factory.makePerson()
228- spanish = getUtility(ILanguageSet).getLanguageByCode('es')
229- user.addLanguage(spanish)
230- self.assertEquals(len(user.languages), 1)
231-
232- login_person(user)
233- view = ProductSeriesView(self.productseries, LaunchpadTestRequest())
234+ language = self.factory.makeLanguage()
235+ user.addLanguage(language)
236+ return user, language
237+
238+ def test_productserieslanguages_preferred_language_without_pofile(self):
239+ # If the user has a preferred language, that language always in
240+ # the list.
241+ self.factory.makePOTemplate(
242+ productseries=self.productseries)
243+ user, language = self._makePersonWithLanguage()
244+ login_person(user)
245+ view = self._createView()
246+ self.assertEquals([language], self._getProductserieslanguages(view))
247+
248+ def test_productserieslanguages_preferred_language_with_pofile(self):
249+ # If the user has a preferred language, that language always in
250+ # the list.
251+ potemplate = self.factory.makePOTemplate(
252+ productseries=self.productseries)
253+ pofile = self.factory.makePOFile(potemplate=potemplate)
254+ user, language = self._makePersonWithLanguage()
255+ login_person(user)
256+ view = self._createView()
257+ self.assertContentEqual(
258+ [pofile.language, language],
259+ self._getProductserieslanguages(view))
260+
261+ def test_productserieslanguages_ordered_by_englishname(self):
262 # Returned languages are ordered by their name in English.
263+ language1 = self.factory.makeLanguage(
264+ language_code='lang-aa', name='Zz')
265+ language2 = self.factory.makeLanguage(
266+ language_code='lang-zz', name='Aa')
267+ potemplate = self.factory.makePOTemplate(
268+ productseries=self.productseries)
269+ self.factory.makePOFile(language=language1, potemplate=potemplate)
270+ self.factory.makePOFile(language=language2, potemplate=potemplate)
271+ view = self._createView()
272 self.assertEquals(
273- [psl.language.englishname for psl in view.productserieslanguages],
274- [u'Serbian', u'Spanish'])
275+ [language2, language1], self._getProductserieslanguages(view))
276
277 def test_productserieslanguages_english(self):
278- # Even if there's an English POFile, it's not listed
279- # among translated languages.
280+ # English is not listed among translated languages, even if there's
281+ # an English POFile
282 potemplate = self.factory.makePOTemplate(
283 productseries=self.productseries)
284- pofile = self.factory.makePOFile('en', potemplate)
285- self.assertEquals(self.view.productserieslanguages,
286- [])
287+ self.factory.makePOFile('en', potemplate)
288+ view = self._createView()
289+ self.assertEquals([], self._getProductserieslanguages(view))
290
291 # It's not shown even with more than one POTemplate
292 # (different code paths).
293- potemplate2 = self.factory.makePOTemplate(
294- productseries=self.productseries)
295- self.assertEquals(self.view.productserieslanguages,
296- [])
297-
298-
299-class TestProductSeriesLanguage(TestCaseWithFactory):
300+ self.factory.makePOTemplate(productseries=self.productseries)
301+ self.assertEquals([], self._getProductserieslanguages(view))
302+
303+
304+class TestProductSeriesLanguageView(TestCaseWithFactory):
305 """Test ProductSeriesLanguage view."""
306
307 layer = LaunchpadZopelessLayer
308
309 def setUp(self):
310 # Create a productseries that uses translations.
311- TestCaseWithFactory.setUp(self)
312+ super(TestProductSeriesLanguageView, self).setUp()
313 self.productseries = self.factory.makeProductSeries()
314 self.productseries.product.official_rosetta = True
315- self.language = getUtility(ILanguageSet).getLanguageByCode('sr')
316+ self.language = self.factory.makeLanguage()
317 potemplate = self.factory.makePOTemplate(
318 productseries=self.productseries)
319- pofile = self.factory.makePOFile('sr', potemplate)
320+ self.factory.makePOFile(language=self.language, potemplate=potemplate)
321 self.psl = self.productseries.productserieslanguages[0]
322- self.view = ProductSeriesLanguageView(
323- self.psl, LaunchpadTestRequest())
324-
325- def test_empty_view(self):
326- self.assertEquals(self.view.translation_group, None)
327- self.assertEquals(self.view.translation_team, None)
328- self.assertEquals(self.view.context, self.psl)
329+
330+ def _createView(self):
331+ view = ProductSeriesLanguageView(self.psl, LaunchpadTestRequest())
332+ view.initialize()
333+ return view
334+
335+ def test_translation_group_no_group(self):
336+ view = self._createView()
337+ self.assertEquals(None, view.translation_group)
338+
339+ def test_translation_team_no_group_no_team(self):
340+ view = self._createView()
341+ self.assertEquals(None, view.translation_team)
342+
343+ def _makeTranslationGroup(self):
344+ group = self.factory.makeTranslationGroup(
345+ self.productseries.product.owner, url=None)
346+ self.productseries.product.translationgroup = group
347+ return group
348
349 def test_translation_group(self):
350- group = self.factory.makeTranslationGroup(
351- self.productseries.product.owner, url=None)
352- self.productseries.product.translationgroup = group
353- self.view.initialize()
354- self.assertEquals(self.view.translation_group, group)
355+ group = self._makeTranslationGroup()
356+ view = self._createView()
357+ self.assertEquals(group, view.translation_group)
358
359- def test_translation_team(self):
360+ def test_translation_team_no_translator(self):
361 # Just having a group doesn't mean there's a translation
362 # team as well.
363- group = self.factory.makeTranslationGroup(
364- self.productseries.product.owner, url=None)
365- self.productseries.product.translationgroup = group
366- self.assertEquals(self.view.translation_team, None)
367+ self._makeTranslationGroup()
368+ view = self._createView()
369+ self.assertEquals(None, view.translation_team)
370
371+ def test_translation_team(self):
372 # Setting a translator for this languages makes it
373 # appear as the translation_team.
374- team = self.factory.makeTeam()
375- translator = getUtility(ITranslatorSet).new(
376- group, self.language, team)
377- # Recreate the view because we are using a cached property.
378- self.view = ProductSeriesLanguageView(
379- self.psl, LaunchpadTestRequest())
380- self.view.initialize()
381- self.assertEquals(self.view.translation_team, translator)
382+ group = self._makeTranslationGroup()
383+ translator = self.factory.makeTranslator(
384+ group=group, language=self.language)
385+ view = self._createView()
386+ self.assertEquals(translator, view.translation_team)