Merge lp:~jonas-drange/ubuntu-system-settings/fix-1240875 into lp:ubuntu-system-settings

Proposed by Jonas G. Drange
Status: Merged
Approved by: Ken VanDine
Approved revision: 989
Merged at revision: 992
Proposed branch: lp:~jonas-drange/ubuntu-system-settings/fix-1240875
Merge into: lp:ubuntu-system-settings
Diff against target: 565 lines (+365/-7)
12 files modified
plugins/language/CMakeLists.txt (+2/-1)
plugins/language/DisplayLanguage.qml (+12/-5)
plugins/language/PageComponent.qml (+25/-1)
plugins/language/RebootNecessary.qml (+53/-0)
plugins/language/language-plugin.cpp (+5/-0)
plugins/language/language-plugin.h (+4/-0)
src/CMakeLists.txt (+4/-0)
src/sessionservice.cpp (+42/-0)
src/sessionservice.h (+40/-0)
tests/autopilot/ubuntu_system_settings/__init__.py (+101/-0)
tests/autopilot/ubuntu_system_settings/tests/__init__.py (+37/-0)
tests/autopilot/ubuntu_system_settings/tests/test_language.py (+40/-0)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-system-settings/fix-1240875
Reviewer Review Type Date Requested Status
Ken VanDine Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+233054@code.launchpad.net

Commit message

[language] explain to the user that a reboot is necessary for the change to take effect

Description of the change

Hi,

This branch changes the UI for changing the display language. After you've confirmed a language change, a dialog will appear, prompting you to reboot the device or revert the change you made.

To be able to reboot the device, I have written a new library for USS. It's called sessionservice and currently offers functionality to reboot the device. It is modelled after accountservice and can be included by any USS plugin.

Thanks

 * Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Yes
 * Did you build your software in a clean sbuild/pbuilder chroot or ppa?
No
 * Did you build your software in a clean sbuild/pbuilder armhf chroot or ppa?
No
 * Has your component "TestPlan” been executed successfully on emulator, N4?
No – waiting for debs
 * Has a 5 minute exploratory testing run been executed on N4?
No
 * If you changed the packaging (debian), did you subscribe a core-dev to this MP?
N/A
 * If you changed the UI, did you subscribe the design-reviewers to this MP?
I'll notify @mpt
 * What components might get impacted by your changes?
The language panel
 * Have you requested review by the teams of these owning components?
Yes

To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

Thanks, that looks fine but it's not very useful to tell the user they need to reboot if we don't expose a reboot command in the UI anywhere...

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks fine, the lack of an obvious way to reboot is an unrelated issue.

review: Approve
Revision history for this message
Ken VanDine (ken-vandine) wrote :

Perhaps this dialog should include a "Reboot now" button?

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I talked to @mpt, lets make the dialog reboot on confirmation or revert.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
989. By Jonas G. Drange

making cleanup more robust, using helper to find element lazily loaded in listview

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks good, tested on mako image 220

review: Approve
Revision history for this message
Adolfo Jayme Barrientos (fitojb) wrote :

Hi, just chiming in to remind you guys that the POT file needs to be updated when introducing new strings, preferably in the same MP, so that translators can do their work with a bigger time window. Thanks!

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

@fitojb Hi, I don't know what that means.

Revision history for this message
Sebastien Bacher (seb128) wrote :

@Jonas, it means somebody needs to run "make pot" and commit an updated po/ubuntu-system-settings.pot so new strings are translatable

@Adolfo, we do that regularly, we just can't do it at every commit

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/language/CMakeLists.txt'
2--- plugins/language/CMakeLists.txt 2014-01-27 16:05:26 +0000
3+++ plugins/language/CMakeLists.txt 2014-09-03 22:02:11 +0000
4@@ -6,6 +6,7 @@
5 KeyboardLayoutItem.qml
6 KeyboardLayouts.qml
7 PageComponent.qml
8+ RebootNecessary.qml
9 SpellChecking.qml
10 SubsetView.qml
11 )
12@@ -15,7 +16,7 @@
13 keyboard-layout.h language-plugin.h plugin.h subset-model.h
14 ${QML_SOURCES})
15 qt5_use_modules(UbuntuLanguagePlugin Qml Quick DBus)
16-target_link_libraries(UbuntuLanguagePlugin ${GLIB_LDFLAGS} ${GIO_LDFLAGS} ${ACCOUNTSSERVICE_LDFLAGS} ${ICU_LDFLAGS})
17+target_link_libraries(UbuntuLanguagePlugin uss-sessionservice ${GLIB_LDFLAGS} ${GIO_LDFLAGS} ${ACCOUNTSSERVICE_LDFLAGS} ${ICU_LDFLAGS})
18
19 set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/LanguagePlugin)
20 install(TARGETS UbuntuLanguagePlugin DESTINATION ${PLUG_DIR})
21
22=== modified file 'plugins/language/DisplayLanguage.qml'
23--- plugins/language/DisplayLanguage.qml 2014-02-27 21:17:09 +0000
24+++ plugins/language/DisplayLanguage.qml 2014-09-03 22:02:11 +0000
25@@ -26,9 +26,12 @@
26
27 SheetBase {
28 id: root
29+ objectName: "displayLanguageDialog"
30
31 property string initialLanguage
32
33+ signal languageChanged (int newLanguage, int oldLanguage)
34+
35 modal: true
36 title: i18n.tr("Display language")
37
38@@ -41,7 +44,7 @@
39
40 ListView {
41 id: languageList
42-
43+ objectName: "languagesList"
44 clip: true
45
46 anchors.top: parent.top
47@@ -59,6 +62,7 @@
48
49 model: plugin.languageNames
50 delegate: ListItem.Standard {
51+ objectName: "languageName" + index
52 text: modelData
53 selected: index == languageList.currentIndex
54
55@@ -90,7 +94,7 @@
56
57 Button {
58 id: cancelButton
59-
60+ objectName: "cancelChangeLanguage"
61 text: i18n.tr("Cancel")
62
63 anchors.left: parent.left
64@@ -110,7 +114,7 @@
65
66 Button {
67 id: confirmButton
68-
69+ objectName: "confirmChangeLanguage"
70 text: i18n.tr("Confirm")
71 enabled: languageList.currentIndex != plugin.currentLanguage
72
73@@ -123,8 +127,11 @@
74 anchors.bottomMargin: units.gu(1)
75
76 onClicked: {
77- plugin.currentLanguage = languageList.currentIndex
78- PopupUtils.close(root)
79+ var oldLang = plugin.currentLanguage;
80+ var newLang = languageList.currentIndex;
81+ languageChanged(newLang, oldLang);
82+ plugin.currentLanguage = newLang;
83+ PopupUtils.close(root);
84 }
85 }
86 }
87
88=== modified file 'plugins/language/PageComponent.qml'
89--- plugins/language/PageComponent.qml 2014-08-11 16:11:20 +0000
90+++ plugins/language/PageComponent.qml 2014-09-03 22:02:11 +0000
91@@ -29,6 +29,7 @@
92
93 ItemPage {
94 id: root
95+ objectName: "languagePage"
96
97 title: i18n.tr("Language & Text")
98
99@@ -39,7 +40,13 @@
100 Component {
101 id: displayLanguage
102
103- DisplayLanguage {}
104+ DisplayLanguage {
105+ onLanguageChanged: {
106+ PopupUtils.open(rebootNecessaryNotification, root, {
107+ revertTo: oldLanguage
108+ })
109+ }
110+ }
111 }
112
113 Component {
114@@ -54,6 +61,20 @@
115 SpellChecking {}
116 }
117
118+ Component {
119+ id: rebootNecessaryNotification
120+
121+ RebootNecessary {
122+
123+ onReboot: {
124+ plugin.reboot();
125+ }
126+ onRevert: {
127+ plugin.currentLanguage = to;
128+ }
129+ }
130+ }
131+
132 GSettings {
133 id: settings
134
135@@ -77,7 +98,10 @@
136 Menus.StandardMenu {
137 iconSource: "image://theme/language-chooser"
138 text: i18n.tr("Display language…")
139+ objectName: "displayLanguage"
140 component: Label {
141+ property int currentLanguage: plugin.currentLanguage
142+ objectName: "currentLanguage"
143 text: plugin.languageNames[plugin.currentLanguage]
144 elide: Text.ElideRight
145 opacity: enabled ? 1.0 : 0.5
146
147=== added file 'plugins/language/RebootNecessary.qml'
148--- plugins/language/RebootNecessary.qml 1970-01-01 00:00:00 +0000
149+++ plugins/language/RebootNecessary.qml 2014-09-03 22:02:11 +0000
150@@ -0,0 +1,53 @@
151+/*
152+ * This file is part of system-settings
153+ *
154+ * Copyright (C) 2014 Canonical Ltd.
155+ *
156+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
157+ *
158+ * This program is free software: you can redistribute it and/or modify it
159+ * under the terms of the GNU General Public License version 3, as published
160+ * by the Free Software Foundation.
161+ *
162+ * This program is distributed in the hope that it will be useful, but
163+ * WITHOUT ANY WARRANTY; without even the implied warranties of
164+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
165+ * PURPOSE. See the GNU General Public License for more details.
166+ *
167+ * You should have received a copy of the GNU General Public License along
168+ * with this program. If not, see <http://www.gnu.org/licenses/>.
169+ */
170+
171+import QtQuick 2.0
172+import Ubuntu.Components 0.1
173+import Ubuntu.Components.Popups 0.1
174+
175+Dialog {
176+ id: dialog
177+ objectName: "rebootNecessaryDialog"
178+
179+ property int revertTo
180+
181+ signal reboot()
182+ signal revert(int to)
183+
184+ text: i18n.tr("The phone needs to restart for changes to take effect.")
185+ Button {
186+ id: reboot
187+ objectName: "reboot"
188+ text: i18n.tr("Restart Now")
189+ onClicked: {
190+ dialog.reboot();
191+ PopupUtils.close(dialog)
192+ }
193+ }
194+ Button {
195+ id: revert
196+ objectName: "revert"
197+ text: i18n.tr("Cancel")
198+ onClicked: {
199+ dialog.revert(revertTo);
200+ PopupUtils.close(dialog)
201+ }
202+ }
203+}
204
205=== modified file 'plugins/language/language-plugin.cpp'
206--- plugins/language/language-plugin.cpp 2014-08-28 07:22:28 +0000
207+++ plugins/language/language-plugin.cpp 2014-09-03 22:02:11 +0000
208@@ -594,3 +594,8 @@
209 LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
210 plugin->enabledLayoutsChanged();
211 }
212+
213+void LanguagePlugin::reboot()
214+{
215+ m_sessionService.reboot();
216+}
217
218=== modified file 'plugins/language/language-plugin.h'
219--- plugins/language/language-plugin.h 2014-08-28 07:22:28 +0000
220+++ plugins/language/language-plugin.h 2014-09-03 22:02:11 +0000
221@@ -23,6 +23,7 @@
222
223 #include <QtCore>
224 #include "subset-model.h"
225+#include "sessionservice.h"
226
227 typedef struct _ActUser ActUser;
228 typedef struct _ActUserManager ActUserManager;
229@@ -63,6 +64,8 @@
230 READ spellCheckingModel
231 CONSTANT)
232
233+ Q_INVOKABLE void reboot();
234+
235 explicit LanguagePlugin(QObject *parent = nullptr);
236
237 virtual ~LanguagePlugin();
238@@ -122,6 +125,7 @@
239 QList<KeyboardLayout *> m_keyboardLayouts;
240 SubsetModel m_keyboardLayoutsModel;
241 SubsetModel m_spellCheckingModel;
242+ SessionService m_sessionService;
243 };
244
245 #endif // LANGUAGE_PLUGIN_H
246
247=== modified file 'src/CMakeLists.txt'
248--- src/CMakeLists.txt 2014-02-13 15:27:47 +0000
249+++ src/CMakeLists.txt 2014-09-03 22:02:11 +0000
250@@ -33,6 +33,10 @@
251 install(TARGETS system-settings RUNTIME DESTINATION bin)
252
253 add_library(uss-accountsservice SHARED accountsservice.h accountsservice.cpp)
254+add_library(uss-sessionservice SHARED sessionservice.h sessionservice.cpp)
255 qt5_use_modules(uss-accountsservice Core Qml DBus)
256+qt5_use_modules(uss-sessionservice Core Qml DBus)
257 set_target_properties(uss-accountsservice PROPERTIES VERSION 0.0 SOVERSION 0.0)
258+set_target_properties(uss-sessionservice PROPERTIES VERSION 0.0 SOVERSION 0.0)
259 install(TARGETS uss-accountsservice LIBRARY DESTINATION ${PLUGIN_MODULE_DIR} NAMELINK_SKIP)
260+install(TARGETS uss-sessionservice LIBRARY DESTINATION ${PLUGIN_MODULE_DIR} NAMELINK_SKIP)
261
262=== added file 'src/sessionservice.cpp'
263--- src/sessionservice.cpp 1970-01-01 00:00:00 +0000
264+++ src/sessionservice.cpp 2014-09-03 22:02:11 +0000
265@@ -0,0 +1,42 @@
266+/*
267+ * This file is part of system-settings
268+ *
269+ * Copyright (C) 2014 Canonical Ltd.
270+ *
271+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
272+ *
273+ * This program is free software: you can redistribute it and/or modify it
274+ * under the terms of the GNU General Public License version 3, as published
275+ * by the Free Software Foundation.
276+ *
277+ * This program is distributed in the hope that it will be useful, but
278+ * WITHOUT ANY WARRANTY; without even the implied warranties of
279+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
280+ * PURPOSE. See the GNU General Public License for more details.
281+ *
282+ * You should have received a copy of the GNU General Public License along
283+ * with this program. If not, see <http://www.gnu.org/licenses/>.
284+ */
285+
286+#include "sessionservice.h"
287+
288+#include <QDebug>
289+
290+#define LM_SERVICE "org.freedesktop.login1"
291+#define LM_PATH "/org/freedesktop/login1"
292+#define LM_IFACE "org.freedesktop.login1.Manager"
293+
294+SessionService::SessionService(QObject *parent)
295+ : QObject(parent),
296+ m_systemBusConnection(QDBusConnection::systemBus()),
297+ m_loginManager(LM_SERVICE,
298+ LM_PATH,
299+ LM_IFACE,
300+ m_systemBusConnection)
301+{
302+}
303+
304+void SessionService::reboot()
305+{
306+ m_loginManager.call("Reboot", false);
307+}
308
309=== added file 'src/sessionservice.h'
310--- src/sessionservice.h 1970-01-01 00:00:00 +0000
311+++ src/sessionservice.h 2014-09-03 22:02:11 +0000
312@@ -0,0 +1,40 @@
313+/*
314+ * This file is part of system-settings
315+ *
316+ * Copyright (C) 2014 Canonical Ltd.
317+ *
318+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
319+ *
320+ * This program is free software: you can redistribute it and/or modify it
321+ * under the terms of the GNU General Public License version 3, as published
322+ * by the Free Software Foundation.
323+ *
324+ * This program is distributed in the hope that it will be useful, but
325+ * WITHOUT ANY WARRANTY; without even the implied warranties of
326+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
327+ * PURPOSE. See the GNU General Public License for more details.
328+ *
329+ * You should have received a copy of the GNU General Public License along
330+ * with this program. If not, see <http://www.gnu.org/licenses/>.
331+ */
332+
333+#ifndef SESSIONSERVICE_H
334+#define SESSIONSERVICE_H
335+
336+#include <QtDBus/QDBusInterface>
337+
338+class SessionService : public QObject
339+{
340+ Q_OBJECT
341+
342+public:
343+ explicit SessionService (QObject *parent = 0);
344+ void reboot();
345+
346+private:
347+ QDBusConnection m_systemBusConnection;
348+ QDBusInterface m_loginManager;
349+
350+};
351+
352+#endif // SESSIONSERVICE_H
353
354=== modified file 'tests/autopilot/ubuntu_system_settings/__init__.py'
355--- tests/autopilot/ubuntu_system_settings/__init__.py 2014-08-26 01:12:17 +0000
356+++ tests/autopilot/ubuntu_system_settings/__init__.py 2014-09-03 22:02:11 +0000
357@@ -110,6 +110,10 @@
358 def go_to_reset_phone(self):
359 return self._go_to_page('entryComponent-reset', 'resetPage')
360
361+ @autopilot.logging.log_action(logger.debug)
362+ def go_to_language_page(self):
363+ return self._go_to_page('entryComponent-language', 'languagePage')
364+
365 def _go_to_page(self, item_object_name, page_object_name):
366 self.click_item(item_object_name)
367 page = self.wait_select_single(objectName=page_object_name)
368@@ -553,3 +557,100 @@
369 def confirm_reset(self):
370 button = self.select_single('Button', objectName='factoryResetAction')
371 self.pointing_device.click_object(button)
372+
373+
374+class LanguagePage(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
375+
376+ """Autopilot helper for the Language page."""
377+
378+ @classmethod
379+ def validate_dbus_object(cls, path, state):
380+ name = introspection.get_classname_from_path(path)
381+ if name == b'ItemPage':
382+ if state['objectName'][1] == 'languagePage':
383+ return True
384+ return False
385+
386+ def get_current_language(self):
387+ return self.select_single(
388+ 'Label', objectName='currentLanguage').currentLanguage
389+
390+ def _click_change_display_language(self):
391+ item = self.select_single(objectName='displayLanguage')
392+ self.pointing_device.click_object(item)
393+ return self.get_root_instance().select_single(
394+ objectName='displayLanguageDialog')
395+
396+ @autopilot.logging.log_action(logger.info)
397+ def change_display_language(self, langIndex, reboot=True):
398+ """Changes display language.
399+
400+ :param langIndex: The language index to change to.
401+
402+ :param reboot: Whether to reboot or not
403+
404+ :returns: The language page
405+
406+ """
407+ dialog = self._click_change_display_language()
408+ dialog.set_language(langIndex, reboot)
409+ return self.get_root_instance()
410+
411+
412+class DisplayLanguage(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
413+
414+ """Autopilot helper for the Display Language dialog."""
415+
416+ @autopilot.logging.log_action(logger.debug)
417+ def set_language(self, index, reboot):
418+ self._click_language_item(index)
419+ reboot_dialog = self._click_confirm()
420+
421+ if reboot:
422+ reboot_dialog.reboot()
423+ else:
424+ reboot_dialog.revert()
425+
426+ @autopilot.logging.log_action(logger.debug)
427+ def _click_language_item(self, index):
428+ languages_list = self.select_single('QQuickListView',
429+ objectName='languagesList')
430+ languages_list.click_element('languageName%d' % index)
431+
432+ @autopilot.logging.log_action(logger.debug)
433+ def _click_confirm(self):
434+ button = self.select_single('Button',
435+ objectName='confirmChangeLanguage')
436+ self.pointing_device.click_object(button)
437+ return self.get_root_instance().select_single(
438+ objectName='rebootNecessaryDialog')
439+
440+ @autopilot.logging.log_action(logger.debug)
441+ def _click_cancel(self):
442+ button = self.select_single('Button',
443+ objectName='cancelChangeLanguage')
444+ self.pointing_device.click_object(button)
445+
446+
447+class RebootNecessary(
448+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
449+
450+ """Autopilot helper for the Reboot Necessary dialog."""
451+
452+ @autopilot.logging.log_action(logger.debug)
453+ def reboot(self):
454+ self._click_reboot()
455+
456+ @autopilot.logging.log_action(logger.debug)
457+ def revert(self):
458+ self._click_revert()
459+
460+ @autopilot.logging.log_action(logger.debug)
461+ def _click_reboot(self):
462+ button = self.select_single('Button', objectName='reboot')
463+ self.pointing_device.click_object(button)
464+
465+ @autopilot.logging.log_action(logger.debug)
466+ def _click_revert(self):
467+ button = self.select_single('Button', objectName='revert')
468+ self.pointing_device.click_object(button)
469
470=== modified file 'tests/autopilot/ubuntu_system_settings/tests/__init__.py'
471--- tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-08-28 17:33:40 +0000
472+++ tests/autopilot/ubuntu_system_settings/tests/__init__.py 2014-09-03 22:02:11 +0000
473@@ -38,6 +38,9 @@
474 CALL_SETTINGS_IFACE = 'org.ofono.CallSettings'
475 SYSTEM_IFACE = 'com.canonical.SystemImage'
476 SYSTEM_SERVICE_OBJ = '/Service'
477+LM_SERVICE = 'org.freedesktop.login1'
478+LM_PATH = '/org/freedesktop/login1'
479+LM_IFACE = 'org.freedesktop.login1.Manager'
480
481
482 class UbuntuSystemSettingsTestCase(
483@@ -696,3 +699,37 @@
484
485 def tearDown(self):
486 super(PhoneSoundBaseTestCase, self).tearDown()
487+
488+
489+class LanguageBaseTestCase(UbuntuSystemSettingsTestCase,
490+ dbusmock.DBusTestCase):
491+ """ Base class for language settings tests"""
492+
493+ def mock_loginmanager(self):
494+ self.mock_server = self.spawn_server(LM_SERVICE, LM_PATH,
495+ LM_IFACE, system_bus=True,
496+ stdout=subprocess.PIPE)
497+ # spawn_server does not wait properly
498+ # Reported as bug here: http://pad.lv/1350833
499+ sleep(2)
500+ self.session_mock = dbus.Interface(self.dbus_con.get_object(
501+ LM_SERVICE, LM_PATH), dbusmock.MOCK_IFACE)
502+
503+ self.session_mock.AddMethod(LM_IFACE, 'Reboot', 'b', '', '')
504+
505+ @classmethod
506+ def setUpClass(klass):
507+ klass.start_system_bus()
508+ klass.dbus_con = klass.get_dbus(True)
509+
510+ def setUp(self):
511+ self.mock_loginmanager()
512+
513+ super(LanguageBaseTestCase, self).setUp()
514+ self.language_page = self.system_settings.\
515+ main_view.go_to_language_page()
516+
517+ def tearDown(self):
518+ self.mock_server.terminate()
519+ self.mock_server.wait()
520+ super(LanguageBaseTestCase, self).tearDown()
521
522=== added file 'tests/autopilot/ubuntu_system_settings/tests/test_language.py'
523--- tests/autopilot/ubuntu_system_settings/tests/test_language.py 1970-01-01 00:00:00 +0000
524+++ tests/autopilot/ubuntu_system_settings/tests/test_language.py 2014-09-03 22:02:11 +0000
525@@ -0,0 +1,40 @@
526+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
527+# Copyright 2014 Canonical
528+#
529+# This program is free software: you can redistribute it and/or modify it
530+# under the terms of the GNU General Public License version 3, as published
531+# by the Free Software Foundation.
532+
533+from __future__ import absolute_import
534+
535+from autopilot.matchers import Eventually
536+from testtools.matchers import Contains, Equals
537+from ubuntu_system_settings.tests import LanguageBaseTestCase
538+from ubuntu_system_settings.utils.i18n import ugettext as _
539+
540+
541+class LanguageTestCase(LanguageBaseTestCase):
542+ """Tests for Language Page"""
543+
544+ def test_language_page_title_is_correct(self):
545+ """Checks whether Language page is available"""
546+ self.assertThat(
547+ self.language_page.title,
548+ Equals(_('Language & Text')))
549+
550+ def test_change_language(self):
551+ current_language = self.language_page.get_current_language()
552+ target_language = current_language + 1
553+ self.language_page.change_display_language(target_language)
554+
555+ self.assertThat(
556+ lambda:
557+ self.language_page.get_current_language(),
558+ Eventually(Equals(target_language)))
559+
560+ self.addCleanup(
561+ self.language_page.change_display_language, current_language)
562+
563+ self.assertThat(
564+ lambda: str(self.session_mock.GetCalls()),
565+ Eventually(Contains('Reboot')))

Subscribers

People subscribed via source and target branches