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