Merge lp:~adiroiban/launchpad/bug-492375 into lp:launchpad

Proposed by Adi Roiban
Status: Merged
Merged at revision: not available
Proposed branch: lp:~adiroiban/launchpad/bug-492375
Merge into: lp:launchpad
Diff against target: 509 lines (+251/-28)
14 files modified
lib/canonical/launchpad/javascript/translations/translations.js (+37/-1)
lib/lp/translations/browser/distroseries.py (+9/-1)
lib/lp/translations/browser/productseries.py (+11/-3)
lib/lp/translations/stories/translations/55-rosetta-potemplates.txt (+1/-1)
lib/lp/translations/templates/distribution-translations.pt (+9/-3)
lib/lp/translations/templates/distroseries-langchart.pt (+16/-1)
lib/lp/translations/templates/distroseries-translations.pt (+8/-0)
lib/lp/translations/templates/object-pots.pt (+2/-2)
lib/lp/translations/templates/product-translations.pt (+9/-2)
lib/lp/translations/templates/productseries-translations-languages.pt (+15/-3)
lib/lp/translations/templates/productseries-translations.pt (+10/-2)
lib/lp/translations/templates/translations-macros.pt (+36/-0)
lib/lp/translations/windmill/tests/test_languages.py (+5/-9)
lib/lp/translations/windmill/tests/test_serieslanguages.py (+83/-0)
To merge this branch: bzr merge lp:~adiroiban/launchpad/bug-492375
Reviewer Review Type Date Requested Status
Michael Nelson (community) ui Approve
Muharem Hrnjadovic (community) code-review Approve
Review via email: mp+16279@code.launchpad.net

Commit message

In a series languages table, at pageload, only display preferred languages.

To post a comment you must log in.
Revision history for this message
Adi Roiban (adiroiban) wrote :

= Bug 492375 =
Suppose I want to translate Ubuntu into Romanian.
I will go to: https://translations.edge.launchpad.net/ and click on "Ubuntu Karmic (9.10)"
The next page will be :
https://translations.edge.launchpad.net/ubuntu/karmic/+translations
Then I have to scroll all along the page and search for Romanian in that big and compact list.

== Proposed fix ==
At first page load, only display users preferred languages and display a link for viewing all languages.

Just like we do for source packages:
https://translations.launchpad.net/ubuntu/karmic/+source/gfxboot-theme-ubuntu/

== Pre-implementation notes ==

After a long chat with Danilo and Jeroen we decided it is best to put the class selection login in the template with some help from the view.

== Tests ==

bin/test --layer=TranslationsWindmillLayer -D -t serieslanguages

UI Review screenshots:
 * http://launchpadlibrarian.net/36485928/preferred.png
 * http://launchpadlibrarian.net/36485936/all-languages.png

== Demo and Q/A ==

Access one of the page presenting language series.
For example http://translations.launchpad.dev/ubuntu

If you are not logged in, you will see a list of languages obtained using geoip.
You can click the "View all languages" and the table should display all langauges for Ubuntu.

If you are logged in, it will show only your preferred languages.

Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :
Download full text (20.5 KiB)

Adi Roiban wrote:
> Adi Roiban has proposed merging lp:~adiroiban/launchpad/bug-492375
> into lp:launchpad/devel.
>
> Requested reviews:
> Canonical Launchpad Engineering (launchpad)
> Related bugs:
> #492375 At first, display only translations statistics for preferred
> languages
> https://bugs.launchpad.net/bugs/492375
Hello Adi,

thank you very much for preparing this branch which generally looks
very good. Please see my comments below for more detail.

[..]

> == Tests ==
>
> bin/test --layer=TranslationsWindmillLayer -D -t serieslanguages
All tests pass except for the one "that always fails" as discussed on IRC:
{{{
<adiroiban> al-maisan: ah... that is part of user.ensure_login(self.client)
<adiroiban> and it fails for all windmill tests
}}}

> == Demo and Q/A ==
>
> Access one of the page presenting language series.
> For example http://translations.launchpad.dev/ubuntu
>
> If you are not logged in, you will see a list of languages obtained
> using geoip.
> You can click the "View all languages" and the table should display
> all langauges for Ubuntu.
>
> If you are logged in, it will show only your preferred languages.
This works as described.

> === modified file 'lib/canonical/launchpad/javascript/translations/translations.js'
> --- lib/canonical/launchpad/javascript/translations/translations.js 2009-11-24 09:30:01 +0000
> +++ lib/canonical/launchpad/javascript/translations/translations.js 2009-12-17 14:38:47 +0000
> @@ -116,7 +116,7 @@
> * which is defined in a code fragment that is included in the page via TAL.
> */
> var init_status_choice = function(content_box, index, list) {
> - content_box.setStyle('display', '')
> + content_box.setStyle('display', '');
> var conf = choice_confs[index];
> conf.title = 'Change status to';
> conf.contentBox = content_box;
> @@ -165,6 +165,11 @@
> button_markers.on('click', show_output);
> };
>
> +var toggle_node_visibility = function(node, index, list) {
> + node.toggleClass('unseen');
> + node.toggleClass('seen');
> +};
> +
> /**
> * Set up the import queue page.
> */
> @@ -183,6 +188,37 @@
> spinner_loader.set('innerHTML', '');
> };
>
> +
> +/**
> + * Set up initial the visibility for languages in a serieslanguages table.
"Set up the initial visibility.." ?

> + */
> +translations.initialize_languages_table = function(Y) {
> + Y.all('.not-preferred-language').each(function(node, index, list) {
> + node.addClass('unseen');
> + });
> + Y.all('.preferred-language').each(function(node, index, list) {
> + node.addClass('seen');
> + });
> +};
> +
> +
> +/**
> + * Toggle visibility for languages in a serieslanguages table.
> + */
> +translations.toggle_languages_visibility = function(e) {
> + e.preventDefault();
> + Y.all('.not-preferred-language').each(toggle_node_visibility);
> + var toggle_button = e.currentTarget;
> + if (toggle_button.hasClass('all-languages-visible')) {
> + toggle_button.setContent('View All Languages');
> + toggle_button.removeClass('all-languages-visible');
> + } else {
> + toggle_button.setContent('View Only Preferred Languages');
> + toggle_button...

Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Looks good, thanks Adi!

review: Approve (code-review)
Revision history for this message
Michael Nelson (michael.nelson) wrote :

Hi Adi, this is great!

I'm really glad you all agreed on the JS version - it's great being able to switch between preferred and all languages without a page-load.

I've only got two thoughts regarding things that were not actually changed by your branch:

First, the capitalization of the "Choose preferred languages - View all languages" links (only first word capitalized, as outlined here: https://dev.launchpad.net/UserInterfaceWording#Capitalization

(Just for reference, there are a bunch of useful links for stuff like that at https://dev.launchpad.net/UI/Reviews)

Second, it's a little bit strange that if my preferred language is just "English", then all languages are displayed, but I still see the 'View all languages'/'View preferred languages'. If this is expected that all languages are displayed when a persons preferred language is "English", then I think we should hide the toggle link in that case?

What do you think?

review: Approve (ui)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/javascript/translations/translations.js'
2--- lib/canonical/launchpad/javascript/translations/translations.js 2009-11-24 09:30:01 +0000
3+++ lib/canonical/launchpad/javascript/translations/translations.js 2009-12-21 17:29:17 +0000
4@@ -116,7 +116,7 @@
5 * which is defined in a code fragment that is included in the page via TAL.
6 */
7 var init_status_choice = function(content_box, index, list) {
8- content_box.setStyle('display', '')
9+ content_box.setStyle('display', '');
10 var conf = choice_confs[index];
11 conf.title = 'Change status to';
12 conf.contentBox = content_box;
13@@ -165,6 +165,11 @@
14 button_markers.on('click', show_output);
15 };
16
17+var toggle_node_visibility = function(node, index, list) {
18+ node.toggleClass('unseen');
19+ node.toggleClass('seen');
20+};
21+
22 /**
23 * Set up the import queue page.
24 */
25@@ -183,6 +188,37 @@
26 spinner_loader.set('innerHTML', '');
27 };
28
29+
30+/**
31+ * Set up the initial visibility for languages in a serieslanguages table.
32+ */
33+translations.initialize_languages_table = function(Y) {
34+ Y.all('.not-preferred-language').each(function(node, index, list) {
35+ node.addClass('unseen');
36+ });
37+ Y.all('.preferred-language').each(function(node, index, list) {
38+ node.addClass('seen');
39+ });
40+};
41+
42+
43+/**
44+ * Toggle visibility for languages in a serieslanguages table.
45+ */
46+translations.toggle_languages_visibility = function(e) {
47+ e.preventDefault();
48+ Y.all('.not-preferred-language').each(toggle_node_visibility);
49+ var toggle_button = e.currentTarget;
50+ if (toggle_button.hasClass('all-languages-visible')) {
51+ toggle_button.setContent('View all languages');
52+ toggle_button.removeClass('all-languages-visible');
53+ } else {
54+ toggle_button.setContent('View only preferred languages');
55+ toggle_button.addClass('all-languages-visible');
56+ }
57+};
58+
59+
60 }, "0.1", {
61 // "oop" and "event" are required to fix known bugs in YUI, which
62 // are apparently fixed in a later version.
63
64=== modified file 'lib/lp/translations/browser/distroseries.py'
65--- lib/lp/translations/browser/distroseries.py 2009-10-30 10:09:17 +0000
66+++ lib/lp/translations/browser/distroseries.py 2009-12-21 17:29:17 +0000
67@@ -107,7 +107,6 @@
68 else:
69 self.adminlabel = 'Settings for language packs'
70
71-
72 @cachedproperty
73 def unused_language_packs(self):
74 unused_language_packs = helpers.shortlist(self.context.language_packs)
75@@ -236,6 +235,14 @@
76
77 return sorted(distroserieslangs, key=lambda a: a.language.englishname)
78
79+ def isPreferredLanguage(self, language):
80+ # if there are no preferred languages, mark all
81+ # languages as preferred
82+ if (len(self.translatable_languages) == 0):
83+ return True
84+ else:
85+ return language in self.translatable_languages
86+
87 @property
88 def potemplates(self):
89 return list(self.context.getCurrentTranslationTemplates())
90@@ -245,6 +252,7 @@
91 """Is this DistroSeries the translation focus."""
92 return self.context.distribution.translation_focus == self.context
93
94+
95 class DistroSeriesTranslationsMenu(NavigationMenu):
96
97 usedfor = IDistroSeries
98
99=== modified file 'lib/lp/translations/browser/productseries.py'
100--- lib/lp/translations/browser/productseries.py 2009-12-10 10:46:53 +0000
101+++ lib/lp/translations/browser/productseries.py 2009-12-21 17:29:17 +0000
102@@ -57,6 +57,7 @@
103
104 class ProductSeriesTranslationsMenuMixIn:
105 """Translation menu for `IProductSeries`."""
106+
107 def overview(self):
108 """Return a link to the overview page."""
109 return Link('', 'Overview')
110@@ -275,7 +276,7 @@
111 warning = (
112 "A file could not be uploaded because its "
113 "name matched multiple existing uploads, for "
114- "different templates." )
115+ "different templates.")
116 ul_conflicts = (
117 "The conflicting file name was:<br /> "
118 "<ul><li>%s</li></ul>" % cgi.escape(conflicts[0]))
119@@ -378,6 +379,14 @@
120 return sorted(productserieslangs,
121 key=lambda a: a.language.englishname)
122
123+ def isPreferredLanguage(self, language):
124+ # if there are no preferred languages, mark all
125+ # languages as preferred
126+ if (len(self.translatable_languages) == 0):
127+ return True
128+ else:
129+ return language in self.translatable_languages
130+
131 @property
132 def has_translation_documentation(self):
133 """Are there translation instructions for this product."""
134@@ -421,8 +430,7 @@
135 def change_settings_action(self, action, data):
136 """Change the translation settings."""
137 if (self.context.translations_autoimport_mode !=
138- data['translations_autoimport_mode']
139- ):
140+ data['translations_autoimport_mode']):
141 self.updateContextFromData(data)
142 # Request an initial upload of translation files.
143 getUtility(IRosettaUploadJobSource).create(
144
145=== modified file 'lib/lp/translations/stories/translations/55-rosetta-potemplates.txt'
146--- lib/lp/translations/stories/translations/55-rosetta-potemplates.txt 2009-06-12 16:36:02 +0000
147+++ lib/lp/translations/stories/translations/55-rosetta-potemplates.txt 2009-12-21 17:29:17 +0000
148@@ -90,7 +90,7 @@
149 Next, if he chooses to view all the languages, he should see Japanese
150 among the languages on the page.
151
152- >>> browser.getLink('View Template & All Languages...').click()
153+ >>> browser.getLink('View template & all languages...').click()
154 >>> 'Japanese' in browser.contents
155 True
156
157
158=== modified file 'lib/lp/translations/templates/distribution-translations.pt'
159--- lib/lp/translations/templates/distribution-translations.pt 2009-11-07 16:14:22 +0000
160+++ lib/lp/translations/templates/distribution-translations.pt 2009-12-21 17:29:17 +0000
161@@ -1,13 +1,19 @@
162-
163 <html
164 xmlns="http://www.w3.org/1999/xhtml"
165 xmlns:tal="http://xml.zope.org/namespaces/tal"
166 xmlns:metal="http://xml.zope.org/namespaces/metal"
167 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
168- metal:use-macro="view/macro:page/main_only"
169->
170+ metal:use-macro="view/macro:page/main_only">
171
172 <body>
173+
174+ <div metal:fill-slot="head_epilogue">
175+ <metal:translations-js
176+ use-macro="context/@@+translations-macros/translations-js" />
177+ <metal:languages-table-js
178+ use-macro="context/@@+translations-macros/languages-table-js" />
179+ </div>
180+
181 <div metal:fill-slot="main">
182 <div class="translation-help-links">
183 <a href="https://help.launchpad.net/Translations"
184
185=== modified file 'lib/lp/translations/templates/distroseries-langchart.pt'
186--- lib/lp/translations/templates/distroseries-langchart.pt 2009-07-17 17:59:07 +0000
187+++ lib/lp/translations/templates/distroseries-langchart.pt 2009-12-21 17:29:17 +0000
188@@ -25,7 +25,18 @@
189 </thead>
190
191 <tbody>
192- <tr tal:repeat="drlang view/distroserieslanguages">
193+ <tal:loop tal:repeat="drlang view/distroserieslanguages">
194+ <tal:preferred
195+ condition="python: view.isPreferredLanguage(drlang.language)">
196+ <tal:set-class
197+ define="global series_language_class string:preferred-language" />
198+ </tal:preferred>
199+ <tal:not-preferred
200+ condition="not:python: view.isPreferredLanguage(drlang.language)">
201+ <tal:set-class
202+ define="global series_language_class string:not-preferred-language" />
203+ </tal:not-preferred>
204+ <tr tal:attributes="class series_language_class">
205 <td>
206 <a tal:attributes="href string:${drlang/fmt:url}"
207 tal:content="drlang/language/englishname">
208@@ -72,6 +83,10 @@
209 </tal:count>
210 </td>
211 </tr>
212+ </tal:loop>
213 </tbody>
214 </table>
215+ <metal:languages-table-actions
216+ use-macro="context/@@+translations-macros/languages-table-actions" />
217+
218 </tal:root>
219
220=== modified file 'lib/lp/translations/templates/distroseries-translations.pt'
221--- lib/lp/translations/templates/distroseries-translations.pt 2009-10-23 06:42:09 +0000
222+++ lib/lp/translations/templates/distroseries-translations.pt 2009-12-21 17:29:17 +0000
223@@ -5,6 +5,14 @@
224 metal:use-macro="view/macro:page/main_only">
225
226 <body>
227+
228+ <div metal:fill-slot="head_epilogue">
229+ <metal:translations-js
230+ use-macro="context/@@+translations-macros/translations-js" />
231+ <metal:languages-table-js
232+ use-macro="context/@@+translations-macros/languages-table-js" />
233+ </div>
234+
235 <div metal:fill-slot="main">
236 <div class="translation-help-links">
237 <a href="https://help.launchpad.net/Translations"
238
239=== modified file 'lib/lp/translations/templates/object-pots.pt'
240--- lib/lp/translations/templates/object-pots.pt 2009-07-24 11:25:36 +0000
241+++ lib/lp/translations/templates/object-pots.pt 2009-12-21 17:29:17 +0000
242@@ -81,10 +81,10 @@
243 <div tal:replace="structure potemplate/@@+preferred-chart" />
244
245 <div align="right">
246- [ <a href="/+editmylanguages">Choose Preferred Languages...</a>
247+ [ <a href="/+editmylanguages">Choose preferred languages...</a>
248 &mdash;
249 <a tal:attributes="href potemplate/fmt:url">
250- View Template &amp; All Languages...</a>
251+ View template &amp; all languages...</a>
252 ]
253 </div>
254
255
256=== modified file 'lib/lp/translations/templates/product-translations.pt'
257--- lib/lp/translations/templates/product-translations.pt 2009-11-10 02:02:34 +0000
258+++ lib/lp/translations/templates/product-translations.pt 2009-12-21 17:29:17 +0000
259@@ -2,10 +2,17 @@
260 xmlns="http://www.w3.org/1999/xhtml"
261 xmlns:tal="http://xml.zope.org/namespaces/tal"
262 xmlns:metal="http://xml.zope.org/namespaces/metal"
263- metal:use-macro="view/macro:page/main_only"
264->
265+ metal:use-macro="view/macro:page/main_only">
266
267 <body>
268+
269+ <div metal:fill-slot="head_epilogue">
270+ <metal:translations-js
271+ use-macro="context/@@+translations-macros/translations-js" />
272+ <metal:languages-table-js
273+ use-macro="context/@@+translations-macros/languages-table-js" />
274+ </div>
275+
276 <div metal:fill-slot="main"
277 tal:define="uses_translations view/uses_translations;
278 admin_user context/required:launchpad.TranslationsAdmin">
279
280=== modified file 'lib/lp/translations/templates/productseries-translations-languages.pt'
281--- lib/lp/translations/templates/productseries-translations-languages.pt 2009-11-03 05:50:48 +0000
282+++ lib/lp/translations/templates/productseries-translations-languages.pt 2009-12-21 17:29:17 +0000
283@@ -15,9 +15,18 @@
284 </tr>
285 </thead>
286 <tbody>
287- <tr tal:repeat="language_stats view/productserieslanguages"
288- tal:attributes="class
289- string:stats language-${language_stats/language/code}">
290+ <tal:loop tal:repeat="language_stats view/productserieslanguages">
291+ <tal:preferred
292+ condition="python: view.isPreferredLanguage(language_stats.language)">
293+ <tal:set-class
294+ define="global series_language_class string:stats language-${language_stats/language/code} preferred-language" />
295+ </tal:preferred>
296+ <tal:not-preferred
297+ condition="not:python: view.isPreferredLanguage(language_stats.language)">
298+ <tal:set-class
299+ define="global series_language_class string:stats language-${language_stats/language/code} not-preferred-language" />
300+ </tal:not-preferred>
301+ <tr tal:attributes="class series_language_class">
302 <td>
303 <tal:multiple_pofile condition="not:view/single_potemplate">
304 <a tal:attributes="href language_stats/fmt:url"
305@@ -68,6 +77,9 @@
306 </tal:block>
307 </td>
308 </tr>
309+ </tal:loop>
310 </tbody>
311 </table>
312+ <metal:languages-table-actions
313+ use-macro="context/@@+translations-macros/languages-table-actions" />
314 </tal:root>
315
316=== modified file 'lib/lp/translations/templates/productseries-translations.pt'
317--- lib/lp/translations/templates/productseries-translations.pt 2009-10-31 12:03:43 +0000
318+++ lib/lp/translations/templates/productseries-translations.pt 2009-12-21 17:29:17 +0000
319@@ -2,9 +2,17 @@
320 xmlns="http://www.w3.org/1999/xhtml"
321 xmlns:tal="http://xml.zope.org/namespaces/tal"
322 xmlns:metal="http://xml.zope.org/namespaces/metal"
323- metal:use-macro="view/macro:page/main_only"
324->
325+ metal:use-macro="view/macro:page/main_only">
326+
327 <body>
328+
329+ <div metal:fill-slot="head_epilogue">
330+ <metal:translations-js
331+ use-macro="context/@@+translations-macros/translations-js" />
332+ <metal:languages-table-js
333+ use-macro="context/@@+translations-macros/languages-table-js" />
334+ </div>
335+
336 <div metal:fill-slot="main">
337 <div class="translation-help-links">
338 <a href="https://help.launchpad.net/Translations"
339
340=== modified file 'lib/lp/translations/templates/translations-macros.pt'
341--- lib/lp/translations/templates/translations-macros.pt 2009-12-07 18:42:21 +0000
342+++ lib/lp/translations/templates/translations-macros.pt 2009-12-21 17:29:17 +0000
343@@ -130,5 +130,41 @@
344 </metal:nav-pofile-subpages>
345
346
347+<metal:translations-js define-macro="translations-js">
348+ <script
349+ type="text/javascript"
350+ tal:condition="devmode"
351+ tal:attributes="src string:${icingroot}/build/translations/translations.js">
352+ </script>
353+</metal:translations-js>
354+
355+
356+<metal:languages-table-js define-macro="languages-table-js">
357+ <script type="text/javascript">
358+ LPS.use("node", "translations", function(Y) {
359+ Y.on("click", function(e) {
360+ Y.translations.toggle_languages_visibility(e);
361+ }, "#toggle-languages-visibility");
362+ });
363+ LPS.use( 'translations', 'event', function(Y) {
364+ Y.on('domready', function(e) {
365+ Y.translations.initialize_languages_table(Y);
366+ });
367+ });
368+ </script>
369+</metal:languages-table-js>
370+
371+
372+<metal:languages-table-actions define-macro="languages-table-actions">
373+ <div align="right">
374+ [ <a href="/+editmylanguages">Choose preferred languages...</a>
375+ <tal:has-preferred condition="view/translatable_languages">&mdash;
376+ <a href="#" id="toggle-languages-visibility">
377+ View all languages</a>
378+ </tal:has-preferred>
379+ ]
380+ </div>
381+</metal:languages-table-actions>
382+
383 </tal:root>
384
385
386=== modified file 'lib/lp/translations/windmill/tests/test_languages.py'
387--- lib/lp/translations/windmill/tests/test_languages.py 2009-12-08 11:19:21 +0000
388+++ lib/lp/translations/windmill/tests/test_languages.py 2009-12-21 17:29:17 +0000
389@@ -6,22 +6,19 @@
390 __metaclass__ = type
391 __all__ = []
392
393-import transaction
394-
395 from windmill.authoring import WindmillTestClient
396-from zope.component import getUtility
397
398 from canonical.launchpad.windmill.testing.constants import (
399- FOR_ELEMENT, PAGE_LOAD, SLEEP)
400+ PAGE_LOAD, SLEEP)
401 from lp.translations.windmill.testing import TranslationsWindmillLayer
402 from lp.testing import TestCaseWithFactory
403
404-INPUT_FIELD=(u"//div[contains(@class,'searchform')]"+
405+INPUT_FIELD = (u"//div[contains(@class,'searchform')]"+
406 u"//input[@id='field.search_lang']")
407-FILTER_BUTTON=(u"//div[contains(@class,'searchform')]"+
408+FILTER_BUTTON = (u"//div[contains(@class,'searchform')]"+
409 u"//input[@value='Filter languages']")
410-LANGUAGE=u"//a[contains(@class, 'language') and text()='%s']/parent::li"
411-UNSEEN_VALIDATOR='className|unseen'
412+LANGUAGE = u"//a[contains(@class, 'language') and text()='%s']/parent::li"
413+UNSEEN_VALIDATOR = 'className|unseen'
414
415
416 class LanguagesFilterTest(TestCaseWithFactory):
417@@ -104,4 +101,3 @@
418 u'Mende': True,
419 u'French': True,
420 })
421-
422
423=== added file 'lib/lp/translations/windmill/tests/test_serieslanguages.py'
424--- lib/lp/translations/windmill/tests/test_serieslanguages.py 1970-01-01 00:00:00 +0000
425+++ lib/lp/translations/windmill/tests/test_serieslanguages.py 2009-12-21 17:29:17 +0000
426@@ -0,0 +1,83 @@
427+# Copyright 2009 Canonical Ltd. This software is licensed under the
428+# GNU Affero General Public License version 3 (see the file LICENSE).
429+
430+"""Tests for series languages."""
431+
432+__metaclass__ = type
433+__all__ = []
434+
435+import transaction
436+
437+from windmill.authoring import WindmillTestClient
438+from zope.component import getUtility
439+
440+from canonical.launchpad.windmill.testing.constants import (
441+ PAGE_LOAD, SLEEP)
442+from canonical.launchpad.windmill.testing import lpuser
443+from canonical.launchpad.windmill.testing.lpuser import login_person
444+from lp.translations.windmill.testing import TranslationsWindmillLayer
445+from lp.testing import TestCaseWithFactory
446+
447+LANGUAGE=(u"//table[@id='languagestats']/descendant::a[text()='%s']"
448+ u"/parent::td/parent::tr")
449+UNSEEN_VALIDATOR='className|unseen'
450+
451+
452+class LanguagesSeriesTest(TestCaseWithFactory):
453+ """Tests for serieslanguages."""
454+
455+ layer = TranslationsWindmillLayer
456+
457+ def _toggle_languages_visiblity(self):
458+ self.client.click(id="toggle-languages-visibility")
459+ self.client.waits.sleep(milliseconds=SLEEP)
460+
461+ def _assert_languages_visible(self, languages):
462+ for language, visibility in languages.items():
463+ xpath = LANGUAGE % language
464+ if visibility:
465+ self.client.asserts.assertNotProperty(
466+ xpath=xpath, validator=UNSEEN_VALIDATOR)
467+ else:
468+ self.client.asserts.assertProperty(
469+ xpath=xpath, validator=UNSEEN_VALIDATOR)
470+
471+ def test_serieslanguages_table(self):
472+ """Test for filtering preferred languages in serieslanguages table.
473+
474+ The test cannot fully cover all languages so we just test with a
475+ person having Catalan and Spanish as preferred languages.
476+ """
477+ self.client = WindmillTestClient('SeriesLanguages Tables')
478+ start_url = 'http://translations.launchpad.dev:8085/ubuntu'
479+ user = lpuser.TRANSLATIONS_ADMIN
480+ # Go to the distribution languages page
481+ self.client.open(url=start_url)
482+ self.client.waits.forPageLoad(timeout=PAGE_LOAD)
483+ user.ensure_login(self.client)
484+
485+ # A link will be displayed for viewing all languages
486+ # and only user preferred langauges are displayed
487+ self.client.asserts.assertProperty(
488+ id=u'toggle-languages-visibility',
489+ validator='text|View all languages')
490+ self._assert_languages_visible({
491+ u'Catalan': True,
492+ u'Spanish': True,
493+ u'French': False,
494+ u'Croatian': False,
495+ })
496+
497+ # Toggle language visibility by clicking the toggle link.
498+ self._toggle_languages_visiblity()
499+ self.client.asserts.assertProperty(
500+ id=u'toggle-languages-visibility',
501+ validator='text|View only preferred languages')
502+ # All languages should be visible now
503+ self._assert_languages_visible({
504+ u'Catalan': True,
505+ u'Spanish': True,
506+ u'French': True,
507+ u'Croatian': True,
508+ })
509+