on xenial help sign in
Add a bunch of tests for wizard
commit2e474a24db90c546eb5d87adc2f431f46a9777e2 authorMichael Terry <michael.terry@canonical.com> dateFri 21 Nov 2014, 14:28 (12 years ago) parentc584e65
45 files changed+1042−39
plugins/Wizard/plugin.cpp+1−8 qml/Wizard/Page.qml+2 qml/Wizard/Pages.qml+11−4 qml/Wizard/Pages/10-welcome.qml+4 qml/Wizard/Pages/20-sim.qml+2 qml/Wizard/Pages/30-passwd-type.qml+4 qml/Wizard/Pages/40-wifi.qml+2 qml/Wizard/Pages/50-location.qml+10−14 qml/Wizard/Pages/60-reporting.qml+2 qml/Wizard/Pages/80-finished.qml+2 qml/Wizard/Pages/here-terms.qml+4 qml/Wizard/Pages/passwd-confirm.qml+2−1 qml/Wizard/Pages/passwd-set.qml+1 tests/mocks/CMakeLists.txt+1 tests/mocks/MeeGo/CMakeLists.txt+1 tests/mocks/MeeGo/QOfono/CMakeLists.txt+10 tests/mocks/MeeGo/QOfono/MockOfonoManager.qml+7 tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qml+28 tests/mocks/MeeGo/QOfono/MockQOfono.cpp+54 tests/mocks/MeeGo/QOfono/MockQOfono.h+52 tests/mocks/MeeGo/QOfono/plugin.cpp+33 tests/mocks/MeeGo/QOfono/plugin.h+31 tests/mocks/MeeGo/QOfono/qmldir+4 tests/mocks/QMenuModel/QDBusActionGroup.qml+12 tests/mocks/Ubuntu/CMakeLists.txt+1 tests/mocks/Ubuntu/SystemSettings/CMakeLists.txt+2 tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/CMakeLists.txt+1 tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qml+7 tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/qmldir+2 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txt+10 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cpp+28 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.h+42 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.cpp+26 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.h+31 tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/qmldir+2 tests/mocks/Wizard/MockSystem.cpp+2−1 tests/mocks/Wizard/MockSystem.h+1 tests/mocks/Wizard/mockplugin.cpp+1−8 tests/plugins/Wizard/CMakeLists.txt+9−3 tests/plugins/Wizard/tst_system.cpp+124 tests/qmltests/CMakeLists.txt+1 tests/qmltests/Wizard/licenses/en_US.html+1 tests/qmltests/Wizard/licenses/fr_CA.html+1 tests/qmltests/Wizard/licenses/fr_FR.html+1 tests/qmltests/Wizard/tst_Wizard.qml+469
plugins/Wizard/plugin.cpp+1−8
@@ -20,13 +20,6 @@
2020
2121#include <QtQml/qqml.h>
2222
23−static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
24−{
25− Q_UNUSED(engine)
26− Q_UNUSED(scriptEngine)
27− return new PageList();
28−}
29−
3023static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3124{
3225 Q_UNUSED(engine)
@@ -37,6 +30,6 @@ static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3730void WizardPlugin::registerTypes(const char *uri)
3831{
3932 Q_ASSERT(uri == QLatin1String("Wizard"));
40− qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
33+ qmlRegisterType<PageList>(uri, 0, 1, "PageList");
4134 qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
4235}
qml/Wizard/Page.qml+2
@@ -77,6 +77,7 @@ Item {
7777
7878 StackButton {
7979 id: backButton
80+ objectName: "backButton"
8081 width: buttonWidth
8182 anchors {
8283 left: parent.left
@@ -94,6 +95,7 @@ Item {
9495
9596 Loader {
9697 id: forwardButton
98+ objectName: "forwardButton"
9799 width: buttonWidth
98100 anchors {
99101 right: parent.right
qml/Wizard/Pages.qml+11−4
@@ -29,6 +29,7 @@ Item {
2929 ////
3030
3131 id: root
32+ objectName: "wizardPages"
3233 focus: true
3334 anchors.fill: parent
3435
@@ -39,6 +40,7 @@ Item {
3940
4041 UbuntuSecurityPrivacyPanel {
4142 id: securityPrivacy
43+ objectName: "securityPrivacy"
4244 }
4345
4446 function quitWizard() {
@@ -72,21 +74,26 @@ Item {
7274 visible: status === Image.Ready
7375 }
7476
77+ PageList {
78+ id: pageList
79+ }
80+
7581 PageStack {
7682 id: pageStack
83+ objectName: "pageStack"
7784 anchors.fill: parent
7885
7986 function next() {
8087 // If we've opened any extra (non-main) pages, pop them before
8188 // continuing so back button returns to the previous main page.
82− while (PageList.index < pageStack.depth - 1)
89+ while (pageList.index < pageStack.depth - 1)
8390 pop()
84− load(PageList.next())
91+ load(pageList.next())
8592 }
8693
8794 function prev() {
88− if (PageList.index >= pageStack.depth - 1)
89− PageList.prev() // update PageList.index, but not for extra pages
95+ if (pageList.index >= pageStack.depth - 1)
96+ pageList.prev() // update pageList.index, but not for extra pages
9097 pop()
9198 if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
9299 prev()
qml/Wizard/Pages/10-welcome.qml+4
@@ -22,6 +22,8 @@ import Wizard 0.1
2222import ".." as LocalComponents
2323
2424LocalComponents.Page {
25+ objectName: "languagePage"
26+
2527 title: i18n.tr("Hi!")
2628 forwardButtonSourceComponent: forwardButton
2729
@@ -57,6 +59,7 @@ LocalComponents.Page {
5759
5860 ComboButton {
5961 id: combo
62+ objectName: "languageCombo"
6063 anchors.left: parent.left
6164 anchors.right: parent.right
6265 text: listview.currentItem.text
@@ -67,6 +70,7 @@ LocalComponents.Page {
6770 model: plugin.languageNames
6871 currentIndex: plugin.currentLanguage
6972 delegate: Standard {
73+ objectName: "languageDelegate" + index
7074 text: modelData
7175 onClicked: {
7276 listview.currentIndex = index
qml/Wizard/Pages/20-sim.qml+2
@@ -20,6 +20,8 @@ import Ubuntu.Components 0.1
2020import ".." as LocalComponents
2121
2222LocalComponents.Page {
23+ objectName: "simPage"
24+
2325 title: i18n.tr("Add a SIM card and restart your device")
2426 forwardButtonSourceComponent: forwardButton
2527
qml/Wizard/Pages/30-passwd-type.qml+4
@@ -34,6 +34,8 @@ import ".." as LocalComponents
3434
3535LocalComponents.Page {
3636 id: passwdPage
37+ objectName: "passwdPage"
38+
3739 title: i18n.tr("Lock security")
3840 forwardButtonSourceComponent: forwardButton
3941
@@ -84,6 +86,8 @@ LocalComponents.Page {
8486 selectedIndex: methodToIndex(root.passwordMethod)
8587
8688 delegate: OptionSelectorDelegate {
89+ objectName: "passwdDelegate" + index
90+
8791 // use subText because we want the text to be small, and we have no other way to control it
8892 subText: {
8993 var method = indexToMethod(index)
qml/Wizard/Pages/40-wifi.qml+2
@@ -23,6 +23,8 @@ import ".." as LocalComponents
2323
2424LocalComponents.Page {
2525 id: wifiPage
26+ objectName: "wifiPage"
27+
2628 title: i18n.tr("Connect to Wi‑Fi")
2729 forwardButtonSourceComponent: forwardButton
2830
qml/Wizard/Pages/50-location.qml+10−14
@@ -22,34 +22,26 @@ import Ubuntu.Components 1.1
2222import ".." as LocalComponents
2323
2424LocalComponents.Page {
25+ objectName: "locationPage"
26+
2527 title: i18n.tr("Location")
2628 forwardButtonSourceComponent: forwardButton
2729
2830 property bool pathSet: AccountsService.hereLicensePath !== " " // single space means it's unassigned
29− property bool countSet: false
30− skipValid: pathSet && (AccountsService.hereLicensePath === "" || countSet)
31− skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 0)
32−
33− Connections {
34− target: termsModel
35− onCountChanged: if (pathSet) countSet = true
36− }
37−
38− Connections {
39− target: AccountsService
40− onHereLicensePathChanged: console.log("MIKE path is", AccountsService.hereLicensePath)
41− }
31+ skipValid: pathSet && (AccountsService.hereLicensePath === "" || termsModel.count > 0)
32+ skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 2) // no files but . and ..
4233
4334 FolderListModel {
4435 id: termsModel
4536 folder: AccountsService.hereLicensePath
4637 nameFilters: ["*.html"]
47− showDirs: false
4838 showOnlyReadable: true
39+ showDotAndDotDot: true // so that count == 0 means we're not done scanning yet
4940 }
5041
5142 QMenuModel.QDBusActionGroup {
5243 id: locationActionGroup
44+ objectName: "locationActionGroup"
5345 busType: QMenuModel.DBus.SessionBus
5446 busName: "com.canonical.indicator.location"
5547 objectPath: "/com/canonical/indicator/location"
@@ -72,6 +64,7 @@ LocalComponents.Page {
7264
7365 LocalComponents.CheckableSetting {
7466 id: gpsCheck
67+ objectName: "gpsCheck"
7568 showDivider: false
7669 text: i18n.tr("Using GPS only (less accurate)")
7770 onTriggered: {
@@ -88,6 +81,7 @@ LocalComponents.Page {
8881
8982 LocalComponents.CheckableSetting {
9083 id: hereCheck
84+ objectName: "hereCheck"
9185 showDivider: false
9286 text: i18n.tr("Using GPS, anonymized Wi-Fi and cellular network info (recommended)")
9387 checked: true
@@ -99,6 +93,7 @@ LocalComponents.Page {
9993 }
10094
10195 Label {
96+ objectName: "hereTermsLink"
10297 anchors.left: parent.left
10398 anchors.leftMargin: hereCheck.labelOffset
10499 anchors.right: parent.right
@@ -112,6 +107,7 @@ LocalComponents.Page {
112107
113108 LocalComponents.CheckableSetting {
114109 id: nopeCheck
110+ objectName: "nopeCheck"
115111 showDivider: false
116112 text: i18n.tr("Not at all")
117113 onTriggered: {
qml/Wizard/Pages/60-reporting.qml+2
@@ -19,6 +19,8 @@ import Ubuntu.Components 0.1
1919import ".." as LocalComponents
2020
2121LocalComponents.Page {
22+ objectName: "reportingPage"
23+
2224 title: i18n.tr("Improving your experience")
2325 forwardButtonSourceComponent: forwardButton
2426
qml/Wizard/Pages/80-finished.qml+2
@@ -19,6 +19,8 @@ import Ubuntu.Components 0.1
1919import ".." as LocalComponents
2020
2121LocalComponents.Page {
22+ objectName: "finishedPage"
23+
2224 title: i18n.tr("All done")
2325 forwardButtonSourceComponent: forwardButton
2426 hasBackButton: false
qml/Wizard/Pages/here-terms.qml+4
@@ -22,6 +22,8 @@ import Ubuntu.Web 0.2
2222import ".." as LocalComponents
2323
2424LocalComponents.Page {
25+ objectName: "hereTermsPage"
26+
2527 title: i18n.tr("Terms & Conditions")
2628 customBack: true
2729
@@ -96,6 +98,7 @@ LocalComponents.Page {
9698
9799 Label {
98100 id: termsLabel
101+ objectName: "termsLabel"
99102 anchors.left: parent.left
100103 anchors.right: parent.right
101104 wrapMode: Text.Wrap
@@ -108,6 +111,7 @@ LocalComponents.Page {
108111
109112 WebView {
110113 id: webview
114+ objectName: "webview"
111115 anchors.left: parent.left
112116 anchors.right: parent.right
113117 height: parent.height
qml/Wizard/Pages/passwd-confirm.qml+2−1
@@ -26,7 +26,8 @@ import "../../Components" as UnityComponents
2626 */
2727
2828LocalComponents.Page {
29− id: passwdSetPage
29+ id: passwdConfirmPage
30+ objectName: "passwdConfirmPage"
3031 forwardButtonSourceComponent: forwardButton
3132
3233 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
qml/Wizard/Pages/passwd-set.qml+1
@@ -27,6 +27,7 @@ import "../../Components" as UnityComponents
2727
2828LocalComponents.Page {
2929 id: passwdSetPage
30+ objectName: "passwdSetPage"
3031 forwardButtonSourceComponent: forwardButton
3132
3233 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
tests/mocks/CMakeLists.txt+1
@@ -32,6 +32,7 @@ add_subdirectory(AccountsService)
3232add_subdirectory(GSettings.1.0)
3333add_subdirectory(libusermetrics)
3434add_subdirectory(LightDM)
35+add_subdirectory(MeeGo)
3536add_subdirectory(Powerd)
3637add_subdirectory(QMenuModel)
3738add_subdirectory(Ubuntu)
tests/mocks/MeeGo/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_subdirectory(QOfono)
tests/mocks/MeeGo/QOfono/CMakeLists.txtnew file+10
@@ -0,0 +1,10 @@
1+set(MOCK_QOFONO_SOURCES
2+ plugin.cpp
3+ MockQOfono.cpp
4+)
5+
6+add_library(MockQOfono MODULE ${MOCK_QOFONO_SOURCES})
7+
8+qt5_use_modules(MockQOfono Qml Quick Core)
9+
10+add_unity8_mock(MeeGo.QOfono 0.2 MeeGo/QOfono TARGETS MockQOfono)
tests/mocks/MeeGo/QOfono/MockOfonoManager.qmlnew file+7
@@ -0,0 +1,7 @@
1+import QtQuick 2.3
2+import MeeGo.QOfono 0.2
3+
4+Item {
5+ readonly property var modems: MockQOfono.modems
6+ readonly property bool available: MockQOfono.available
7+}
tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qmlnew file+28
@@ -0,0 +1,28 @@
1+import QtQuick 2.3
2+import MeeGo.QOfono 0.2
3+
4+Item {
5+ id: simManager
6+
7+ property string modemPath
8+ readonly property alias present: d.present
9+
10+ ////
11+
12+ QtObject {
13+ id: d
14+
15+ property bool present: false
16+
17+ function updatePresence() {
18+ d.present = MockQOfono.isModemPresent(simManager.modemPath)
19+ }
20+ }
21+
22+ onModemPathChanged: d.updatePresence()
23+
24+ Connections {
25+ target: MockQOfono
26+ onModemsChanged: d.updatePresence()
27+ }
28+}
tests/mocks/MeeGo/QOfono/MockQOfono.cppnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "MockQOfono.h"
18+
19+MockQOfono::MockQOfono(QObject *parent)
20+ : QObject(parent),
21+ m_available(false),
22+ m_modems()
23+{
24+}
25+
26+bool MockQOfono::available() const
27+{
28+ return m_available;
29+}
30+
31+void MockQOfono::setAvailable(bool available)
32+{
33+ m_available = available;
34+ Q_EMIT availableChanged();
35+}
36+
37+QStringList MockQOfono::modems() const
38+{
39+ return m_modems.keys();
40+}
41+
42+void MockQOfono::setModems(const QStringList &modems, const QList<bool> &present)
43+{
44+ m_modems.clear();
45+ for (int i = 0; i < modems.length(); i++) {
46+ m_modems[modems[i]] = present[i];
47+ }
48+ Q_EMIT modemsChanged();
49+}
50+
51+bool MockQOfono::isModemPresent(const QString &modem)
52+{
53+ return m_modems.value(modem, false);
54+}
tests/mocks/MeeGo/QOfono/MockQOfono.hnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// This class just exists as a backend for the instantiable Qml objects to pull
18+// from. It exists only for this mock plugin.
19+
20+#ifndef MOCK_QOFONO_H
21+#define MOCK_QOFONO_H
22+
23+#include <QObject>
24+#include <QMap>
25+#include <QStringList>
26+
27+class MockQOfono : public QObject
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(bool available READ available WRITE setAvailable NOTIFY availableChanged)
31+ Q_PROPERTY(QStringList modems READ modems NOTIFY modemsChanged)
32+
33+public:
34+ explicit MockQOfono(QObject *parent = 0);
35+
36+ bool available() const;
37+ void setAvailable(bool available);
38+ QStringList modems() const;
39+
40+ Q_INVOKABLE void setModems(const QStringList &modems, const QList<bool> &present);
41+ Q_INVOKABLE bool isModemPresent(const QString &modem);
42+
43+Q_SIGNALS:
44+ void availableChanged();
45+ void modemsChanged();
46+
47+private:
48+ bool m_available;
49+ QMap<QString, bool> m_modems;
50+};
51+
52+#endif // MOCK_QOFONO_H
tests/mocks/MeeGo/QOfono/plugin.cppnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "MockQOfono.h"
19+
20+#include <QtQml>
21+
22+static QObject *mock_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
23+{
24+ Q_UNUSED(engine)
25+ Q_UNUSED(scriptEngine)
26+ return new MockQOfono();
27+}
28+
29+void BackendPlugin::registerTypes(const char *uri)
30+{
31+ Q_ASSERT(uri == QLatin1String("MeeGo.QOfono"));
32+ qmlRegisterSingletonType<MockQOfono>(uri, 0, 2, "MockQOfono", mock_provider); // just for mock
33+}
tests/mocks/MeeGo/QOfono/plugin.hnew file+31
@@ -0,0 +1,31 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MOCK_QOFONO_PLUGIN_H
18+#define MOCK_QOFONO_PLUGIN_H
19+
20+#include <QQmlExtensionPlugin>
21+
22+class BackendPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // MOCK_QOFONO_PLUGIN_H
tests/mocks/MeeGo/QOfono/qmldirnew file+4
@@ -0,0 +1,4 @@
1+module MeeGo.QOfono
2+plugin MockQOfono
3+OfonoManager 0.2 MockOfonoManager.qml
4+OfonoSimManager 0.2 MockOfonoSimManager.qml
tests/mocks/QMenuModel/QDBusActionGroup.qml+12
@@ -21,6 +21,7 @@ import QtQuick 2.0
2121import Ubuntu.Settings.Menus 0.1 as Menus
2222
2323QtObject {
24+ id: actionGroup
2425 property int busType
2526 property string busName
2627 property string objectPath
@@ -78,6 +79,17 @@ QtObject {
7879 'percent': 0.0
7980 }
8081 }
82+ case "gps-detection-enabled":
83+ case "location-detection-enabled":
84+ return Qt.createQmlObject("
85+import QtQuick 2.3
86+QtObject {
87+ property bool valid: true
88+ property bool state: false
89+ function activate() {
90+ state = !state;
91+ }
92+}", actionGroup);
8193 default:
8294 break;
8395 }
tests/mocks/Ubuntu/CMakeLists.txt+1
@@ -2,5 +2,6 @@ add_subdirectory(Connectivity)
22add_subdirectory(DownloadDaemonListener)
33add_subdirectory(Payments)
44add_subdirectory(SystemImage)
5+add_subdirectory(SystemSettings)
56add_subdirectory(Telephony)
67add_subdirectory(Thumbnailer)
tests/mocks/Ubuntu/SystemSettings/CMakeLists.txtnew file+2
@@ -0,0 +1,2 @@
1+add_subdirectory(LanguagePlugin)
2+add_subdirectory(SecurityPrivacy)
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/CMakeLists.txtnew file+1
@@ -0,0 +1 @@
1+add_unity8_mock(Ubuntu.SystemSettings.LanguagePlugin 1.0 Ubuntu/SystemSettings/LanguagePlugin)
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qmlnew file+7
@@ -0,0 +1,7 @@
1+import QtQuick 2.3
2+
3+Item {
4+ property var languageNames: ["English", "French", "Spanish"]
5+ property var languageCodes: ["en", "fr", "es"]
6+ property int currentLanguage: 0
7+}
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Ubuntu.SystemSettings.LanguagePlugin
2+UbuntuLanguagePlugin 1.0 MockLanguagePlugin.qml
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txtnew file+10
@@ -0,0 +1,10 @@
1+set(MOCK_SECURITYPRIVACY_SOURCES
2+ plugin.cpp
3+ MockSecurityPrivacy.cpp
4+)
5+
6+add_library(MockSecurityPrivacy MODULE ${MOCK_SECURITYPRIVACY_SOURCES})
7+
8+qt5_use_modules(MockSecurityPrivacy Qml Quick Core)
9+
10+add_unity8_mock(Ubuntu.SystemSettings.SecurityPrivacy 1.0 Ubuntu/SystemSettings/SecurityPrivacy TARGETS MockSecurityPrivacy)
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cppnew file+28
@@ -0,0 +1,28 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "MockSecurityPrivacy.h"
18+
19+MockSecurityPrivacy::MockSecurityPrivacy(QObject *parent)
20+ : QObject(parent)
21+{
22+}
23+
24+QString MockSecurityPrivacy::setSecurity(const QString &oldPasswd, const QString &newPasswd, SecurityType newType)
25+{
26+ Q_EMIT setSecurityCalled(oldPasswd, newPasswd, newType);
27+ return "";
28+}
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.hnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MOCK_SECURITYPRIVACY_H
18+#define MOCK_SECURITYPRIVACY_H
19+
20+#include <QObject>
21+
22+class MockSecurityPrivacy : public QObject
23+{
24+ Q_OBJECT
25+ Q_ENUMS(SecurityType)
26+
27+public:
28+ enum SecurityType {
29+ Swipe,
30+ Passcode,
31+ Passphrase,
32+ };
33+
34+ MockSecurityPrivacy(QObject *parent = 0);
35+
36+ Q_INVOKABLE QString setSecurity(const QString &oldPasswd, const QString &newPasswd, SecurityType newType);
37+
38+Q_SIGNALS:
39+ void setSecurityCalled(const QString &oldPasswd, const QString &newPasswd, SecurityType newType); // only in mock
40+};
41+
42+#endif // MOCK_SECURITYPRIVACY_H
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.cppnew file+26
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "MockSecurityPrivacy.h"
19+
20+#include <QtQml>
21+
22+void BackendPlugin::registerTypes(const char *uri)
23+{
24+ Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.SecurityPrivacy"));
25+ qmlRegisterType<MockSecurityPrivacy>(uri, 1, 0, "UbuntuSecurityPrivacyPanel");
26+}
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.hnew file+31
@@ -0,0 +1,31 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef MOCK_SECURITYPRIVACY_PLUGIN_H
18+#define MOCK_SECURITYPRIVACY_PLUGIN_H
19+
20+#include <QQmlExtensionPlugin>
21+
22+class BackendPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // MOCK_SECURITYPRIVACY_PLUGIN_H
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module Ubuntu.SystemSettings.SecurityPrivacy
2+plugin MockSecurityPrivacy
tests/mocks/Wizard/MockSystem.cpp+2−1
@@ -33,6 +33,7 @@ void MockSystem::setWizardEnabled(bool enabled)
3333 Q_EMIT wizardEnabledChanged();
3434}
3535
36−void MockSystem::updateSessionLanguage(const QString &)
36+void MockSystem::updateSessionLanguage(const QString &locale)
3737{
38+ Q_EMIT updateSessionLanguageCalled(locale);
3839}
tests/mocks/Wizard/MockSystem.h+1
@@ -36,6 +36,7 @@ public Q_SLOTS:
3636
3737Q_SIGNALS:
3838 void wizardEnabledChanged();
39+ void updateSessionLanguageCalled(const QString &locale); // only in mock
3940
4041private:
4142 Q_DISABLE_COPY(MockSystem)
tests/mocks/Wizard/mockplugin.cpp+1−8
@@ -20,13 +20,6 @@
2020
2121#include <QtQml/qqml.h>
2222
23−static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
24−{
25− Q_UNUSED(engine)
26− Q_UNUSED(scriptEngine)
27− return new PageList();
28−}
29−
3023static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3124{
3225 Q_UNUSED(engine)
@@ -37,6 +30,6 @@ static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3730void MockWizardPlugin::registerTypes(const char *uri)
3831{
3932 Q_ASSERT(uri == QLatin1String("Wizard"));
40− qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
33+ qmlRegisterType<PageList>(uri, 0, 1, "PageList");
4134 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", system_provider);
4235}
tests/plugins/Wizard/CMakeLists.txt+9−3
@@ -3,10 +3,16 @@ include_directories(
33 ${CMAKE_SOURCE_DIR}/plugins/Wizard
44)
55
6−add_executable(tst-pagelist
6+add_executable(tst-wizard-pagelist
77 tst_pagelist.cpp
88 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
99)
10−qt5_use_modules(tst-pagelist Core Qml Test)
10+qt5_use_modules(tst-wizard-pagelist Core Qml Test)
11+add_test(NAME wizardpagelisttest COMMAND env UNITY_TEST_ENV=1 ${CMAKE_CURRENT_BINARY_DIR}/tst-wizard-pagelist)
1112
12−add_test(NAME pagelisttest COMMAND env UNITY_TEST_ENV=1 ${CMAKE_CURRENT_BINARY_DIR}/tst-pagelist)
13+add_executable(tst-wizard-system
14+ tst_system.cpp
15+ ${CMAKE_SOURCE_DIR}/plugins/Wizard/System.cpp
16+)
17+qt5_use_modules(tst-wizard-system Core DBus Qml Test)
18+add_test(NAME wizardsystemtest COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tst-wizard-system)
tests/plugins/Wizard/tst_system.cppnew file+124
@@ -0,0 +1,124 @@
1+/*
2+ * Copyright (C) 2014 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "System.h"
18+
19+#include <QDebug>
20+#include <QObject>
21+#include <QSignalSpy>
22+#include <QTemporaryDir>
23+#include <QTest>
24+
25+class SystemTest: public QObject
26+{
27+ Q_OBJECT
28+
29+public:
30+ SystemTest();
31+
32+private Q_SLOTS:
33+ void testEnable();
34+ void testDisable();
35+ void testNoticeChanges();
36+
37+private:
38+ void enable();
39+ void disable();
40+ bool isEnabled();
41+
42+ QTemporaryDir dir;
43+ QDir enableDir;
44+ QFile enableFile;
45+};
46+
47+SystemTest::SystemTest()
48+{
49+ qputenv("HOME", dir.path().toUtf8());
50+ enableDir.setPath(dir.path() + "/.config/ubuntu-system-settings");
51+ enableFile.setFileName(enableDir.filePath("wizard-has-run"));
52+}
53+
54+void SystemTest::enable()
55+{
56+ enableFile.remove();
57+ QCOMPARE(isEnabled(), true);
58+}
59+
60+void SystemTest::disable()
61+{
62+ enableDir.mkpath(".");
63+ enableFile.open(QIODevice::WriteOnly);
64+ enableFile.close();
65+ QCOMPARE(isEnabled(), false);
66+}
67+
68+bool SystemTest::isEnabled()
69+{
70+ return !enableFile.exists();
71+}
72+
73+void SystemTest::testEnable()
74+{
75+ disable();
76+
77+ System system;
78+ QVERIFY(!system.wizardEnabled());
79+
80+ system.setWizardEnabled(true);
81+ QVERIFY(system.wizardEnabled());
82+ QVERIFY(isEnabled());
83+}
84+
85+void SystemTest::testDisable()
86+{
87+ enable();
88+
89+ System system;
90+ QVERIFY(system.wizardEnabled());
91+
92+ system.setWizardEnabled(false);
93+ QVERIFY(!system.wizardEnabled());
94+ QVERIFY(!isEnabled());
95+}
96+
97+void SystemTest::testNoticeChanges()
98+{
99+ enable();
100+
101+ System system;
102+ QSignalSpy spy(&system, SIGNAL(wizardEnabledChanged()));
103+
104+ // System only guarantees its signals work correcty when using its own set
105+ // methods (i.e. it won't necessarily notice if we modify the file behind
106+ // the scenes). This is because watching all parent directories of the
107+ // wizard-has-run file with QFileSystemWatcher is a nightmare and waste of
108+ // resources for the corner case it is. So we'll just test the set method.
109+
110+ system.setWizardEnabled(false);
111+ QTRY_COMPARE(spy.count(), 1);
112+
113+ system.setWizardEnabled(true);
114+ QTRY_COMPARE(spy.count(), 2);
115+
116+ system.setWizardEnabled(false);
117+ QTRY_COMPARE(spy.count(), 3);
118+
119+ system.setWizardEnabled(true);
120+ QTRY_COMPARE(spy.count(), 4);
121+}
122+
123+QTEST_MAIN(SystemTest)
124+#include "tst_system.moc"
tests/qmltests/CMakeLists.txt+1
@@ -87,3 +87,4 @@ add_qml_test(Stages SpreadDelegate ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_D
8787add_qml_test(Stages SurfaceContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
8888add_qml_test(Stages SessionContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
8989add_qml_test(Stages Splash)
90+add_qml_test(Wizard Wizard)
tests/qmltests/Wizard/licenses/en_US.htmlnew file+1
@@ -0,0 +1 @@
1+en_US
tests/qmltests/Wizard/licenses/fr_CA.htmlnew file+1
@@ -0,0 +1 @@
1+fr_CA
tests/qmltests/Wizard/licenses/fr_FR.htmlnew file+1
@@ -0,0 +1 @@
1+fr_FR
tests/qmltests/Wizard/tst_Wizard.qmlnew file+469
@@ -0,0 +1,469 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.3
18+import QtTest 1.0
19+import AccountsService 0.1
20+import MeeGo.QOfono 0.2
21+import Ubuntu.Components 1.1
22+import Ubuntu.SystemSettings.SecurityPrivacy 1.0
23+import Unity.Test 0.1 as UT
24+import Wizard 0.1
25+import "../../../qml/Wizard"
26+
27+Item {
28+ id: root
29+ width: units.gu(40)
30+ height: units.gu(71)
31+
32+ Loader {
33+ id: wizardLoader
34+ anchors.fill: parent
35+
36+ property bool itemDestroyed: false
37+ sourceComponent: Component {
38+ Wizard {
39+ id: wizard
40+ anchors.fill: parent
41+ background: Qt.resolvedUrl("../../../qml/graphics/phone_background.jpg")
42+
43+ Component.onDestruction: {
44+ wizardLoader.itemDestroyed = true;
45+ }
46+ }
47+ }
48+ }
49+
50+ SignalSpy {
51+ id: updateSessionLanguageSpy
52+ target: System
53+ signalName: "updateSessionLanguageCalled"
54+ }
55+
56+ SignalSpy {
57+ id: setSecuritySpy
58+ signalName: "setSecurityCalled"
59+ }
60+
61+ function setup() {
62+ AccountsService.hereEnabled = false;
63+ AccountsService.hereLicensePath = Qt.resolvedUrl("licenses");
64+ i18n.language = "en";
65+ MockQOfono.setModems(["sim1"], [false]);
66+ MockQOfono.available = true;
67+ System.wizardEnabled = true;
68+
69+ updateSessionLanguageSpy.clear();
70+ setSecuritySpy.clear();
71+ }
72+
73+ Component.onCompleted: {
74+ Theme.name = "Ubuntu.Components.Themes.SuruGradient";
75+ setup();
76+ }
77+
78+ UT.UnityTestCase {
79+ id: wizardTests
80+ name: "Wizard"
81+ when: windowShown
82+
83+ property Item wizard: wizardLoader.status === Loader.Ready ? wizardLoader.item : null
84+
85+ function cleanup() {
86+ wizardLoader.itemDestroyed = false;
87+
88+ wizardLoader.active = false;
89+
90+ tryCompare(wizardLoader, "status", Loader.Null);
91+ tryCompare(wizardLoader, "item", null);
92+ // Loader.status might be Loader.Null and Loader.item might be null but the Loader
93+ // item might still be alive. So if we set Loader.active back to true
94+ // again right now we will get the very same Shell instance back. So no reload
95+ // actually took place. Likely because Loader waits until the next event loop
96+ // iteration to do its work. So to ensure the reload, we will wait until the
97+ // Shell instance gets destroyed.
98+ tryCompare(wizardLoader, "itemDestroyed", true);
99+
100+ // reload our test subject to get it in a fresh state once again
101+ wizardLoader.active = true;
102+
103+ tryCompare(wizardLoader, "status", Loader.Ready);
104+
105+ var pages = findChild(wizard, "wizardPages");
106+ var security = findInvisibleChild(pages, "securityPrivacy");
107+ setSecuritySpy.target = security;
108+
109+ setup();
110+ }
111+
112+ function waitForPage(name) {
113+ var pages = findChild(wizard, "wizardPages");
114+ var stack = findChild(pages, "pageStack");
115+ // don't simply call tryCompare here, because stack.currentPage will be swapped out itself
116+ tryCompareFunction(function() { return stack.currentPage.objectName; }, name);
117+ tryCompare(stack.currentPage, "opacity", 1.0);
118+ tryCompare(stack.currentPage, "enabled", true);
119+ waitForRendering(stack.currentPage);
120+ return stack.currentPage;
121+ }
122+
123+ function goToPage(name, skipSim, skipLocation) {
124+ if (skipSim === undefined) {
125+ skipSim = false;
126+ }
127+ if (skipLocation === undefined) {
128+ skipLocation = false;
129+ }
130+
131+ var page = waitForPage("languagePage");
132+ if (name === page.objectName) return page;
133+ tap(findChild(page, "forwardButton"));
134+
135+ if (!skipSim) {
136+ page = waitForPage("simPage");
137+ if (name === page.objectName) return page;
138+ tap(findChild(page, "forwardButton"));
139+ }
140+
141+ page = waitForPage("passwdPage");
142+ if (name === page.objectName) return page;
143+ tap(findChild(page, "passwdDelegate0"));
144+ tap(findChild(page, "forwardButton"));
145+
146+ page = waitForPage("wifiPage");
147+ if (name === page.objectName) return page;
148+ tap(findChild(page, "forwardButton"));
149+
150+ if (!skipLocation) {
151+ page = waitForPage("locationPage");
152+ if (name === page.objectName) return page;
153+ tap(findChild(page, "forwardButton"));
154+ }
155+
156+ page = waitForPage("reportingPage");
157+ if (name === page.objectName) return page;
158+ tap(findChild(page, "forwardButton"));
159+
160+ page = waitForPage("finishedPage");
161+ if (name === page.objectName) return page;
162+ tap(findChild(page, "forwardButton"));
163+
164+ tryCompare(wizard, "shown", false);
165+ compare(name, null);
166+ return null;
167+ }
168+
169+ function test_languageChange() {
170+ var page = goToPage("languagePage");
171+ tap(findChild(page, "languageCombo"));
172+ waitForRendering(findChild(page, "languageDelegate1"));
173+ wait(100); // still needs more time to finish drawing(?) or else we sometimes fail
174+ tap(findChild(page, "languageDelegate1"));
175+ tryCompare(i18n, "language", "fr");
176+ tap(findChild(page, "forwardButton"));
177+ tryCompare(updateSessionLanguageSpy, "count", 1);
178+ compare(updateSessionLanguageSpy.signalArguments[0][0], "fr");
179+ }
180+
181+ function test_languageNoChange() {
182+ goToPage("simPage"); // one past language page
183+ compare(updateSessionLanguageSpy.count, 0);
184+ }
185+
186+ function test_simUnavailableSkip() {
187+ MockQOfono.available = false;
188+ goToPage("passwdPage", true);
189+ }
190+
191+ function test_simNoModemsSkip() {
192+ MockQOfono.setModems([], []);
193+ goToPage("passwdPage", true);
194+ }
195+
196+ function test_simFirstSkip() {
197+ MockQOfono.setModems(["a", "b"], [true, false]);
198+ goToPage("passwdPage", true);
199+ }
200+
201+ function test_simSecondSkip() {
202+ MockQOfono.setModems(["a", "b"], [false, true]);
203+ goToPage("passwdPage", true);
204+ }
205+
206+ function test_simBothSkip() {
207+ MockQOfono.setModems(["a", "b"], [true, true]);
208+ goToPage("passwdPage", true);
209+ }
210+
211+ function enterPasscode(passcode) {
212+ for (var i = 0; i < passcode.length; ++i) {
213+ var character = passcode.charAt(i);
214+ var button = findChild(wizard, "pinPadButton" + character);
215+ tap(button);
216+ }
217+ }
218+
219+ function test_passwdPasscode() {
220+ var page = goToPage("passwdPage");
221+
222+ tap(findChild(page, "forwardButton"));
223+ page = waitForPage("passwdSetPage");
224+
225+ enterPasscode("1111");
226+ page = waitForPage("passwdConfirmPage");
227+
228+ // make sure we go back to 'set' page not 'type' page
229+ tap(findChild(page, "backButton"));
230+ page = waitForPage("passwdSetPage");
231+
232+ enterPasscode("1111");
233+ page = waitForPage("passwdConfirmPage");
234+
235+ enterPasscode("1112");
236+ var error = findChild(page, "wrongNoticeLabel");
237+ tryCompareFunction(function() { return error.text !== ""; }, true);
238+
239+ enterPasscode("1111");
240+ page = waitForPage("wifiPage");
241+
242+ // now finish up
243+ tap(findChild(page, "forwardButton"));
244+ page = waitForPage("locationPage");
245+ tap(findChild(page, "forwardButton"));
246+ page = waitForPage("reportingPage");
247+ tap(findChild(page, "forwardButton"));
248+ page = waitForPage("finishedPage");
249+ tap(findChild(page, "forwardButton"));
250+
251+ tryCompare(setSecuritySpy, "count", 1);
252+ compare(setSecuritySpy.signalArguments[0][0], "");
253+ compare(setSecuritySpy.signalArguments[0][1], "1111");
254+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Passcode);
255+ }
256+
257+ function test_passwdPassphrase() {
258+ var page = goToPage("passwdPage");
259+ tap(findChild(page, "passwdDelegate2"));
260+
261+ tap(findChild(page, "forwardButton"));
262+ page = waitForPage("passwdSetPage");
263+
264+ typeString("aaa");
265+ var continueButton = findChild(page, "forwardButton");
266+ tryCompare(continueButton.item, "enabled", false);
267+ keyClick(Qt.Key_Enter);
268+ var error = findChild(page, "wrongNoticeLabel");
269+ tryCompareFunction(function() { return error.text !== ""; }, true);
270+
271+ typeString("aaaa");
272+ tap(continueButton);
273+ page = waitForPage("passwdConfirmPage");
274+
275+ // make sure we go back to 'set' page not 'type' page
276+ var back = findChild(page, "backButton");
277+ tap(back);
278+ page = waitForPage("passwdSetPage");
279+
280+ typeString("aaaa");
281+ keyClick(Qt.Key_Enter);
282+ page = waitForPage("passwdConfirmPage");
283+
284+ continueButton = findChild(page, "forwardButton");
285+ typeString("aaab");
286+ tryCompare(continueButton.item, "enabled", false);
287+ keyClick(Qt.Key_Enter);
288+ var error = findChild(page, "wrongNoticeLabel");
289+ tryCompareFunction(function() { return error.text !== ""; }, true);
290+
291+ typeString("aaaa");
292+ tap(continueButton);
293+ page = waitForPage("wifiPage");
294+
295+ // now finish up
296+ tap(findChild(page, "forwardButton"));
297+ page = waitForPage("locationPage");
298+ tap(findChild(page, "forwardButton"));
299+ page = waitForPage("reportingPage");
300+ tap(findChild(page, "forwardButton"));
301+ page = waitForPage("finishedPage");
302+ tap(findChild(page, "forwardButton"));
303+
304+ tryCompare(setSecuritySpy, "count", 1);
305+ compare(setSecuritySpy.signalArguments[0][0], "");
306+ compare(setSecuritySpy.signalArguments[0][1], "aaaa");
307+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Passphrase);
308+ }
309+
310+ function test_passwdSwipe() {
311+ goToPage(null);
312+
313+ tryCompare(setSecuritySpy, "count", 1);
314+ compare(setSecuritySpy.signalArguments[0][0], "");
315+ compare(setSecuritySpy.signalArguments[0][1], "");
316+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Swipe);
317+ }
318+
319+ function test_locationSkipNoPath() {
320+ AccountsService.hereLicensePath = "";
321+ goToPage("reportingPage", false, true);
322+ }
323+
324+ function test_locationSkipNoFiles() {
325+ AccountsService.hereLicensePath = Qt.resolvedUrl("nolicenses");
326+ goToPage("reportingPage", false, true);
327+ }
328+
329+ function test_locationWaitOnPath() {
330+ AccountsService.hereLicensePath = " "; // means we're still getting the path from dbus
331+
332+ var page = goToPage("wifiPage");
333+
334+ var pages = findChild(wizard, "wizardPages");
335+ var stack = findChild(pages, "pageStack");
336+ tap(findChild(page, "forwardButton"));
337+ // don't simply call tryCompare here, because stack.currentPage will be swapped out itself
338+ tryCompareFunction(function() { return stack.currentPage.objectName; }, "locationPage");
339+ compare(stack.currentPage.enabled, false);
340+ compare(stack.currentPage.skipValid, false);
341+
342+ AccountsService.hereLicensePath = "";
343+ waitForPage("reportingPage");
344+ }
345+
346+ function test_locationGpsOnly() {
347+ var page = goToPage("locationPage");
348+ var gpsCheck = findChild(page, "gpsCheck");
349+ var hereCheck = findChild(page, "hereCheck");
350+ var nopeCheck = findChild(page, "nopeCheck");
351+
352+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
353+ tryCompare(locationActionGroup.location, "state", false);
354+ tryCompare(locationActionGroup.gps, "state", false);
355+
356+ tap(gpsCheck);
357+ tryCompare(gpsCheck, "checked", true);
358+ tryCompare(hereCheck, "checked", false);
359+ tryCompare(nopeCheck, "checked", false);
360+
361+ tap(findChild(page, "forwardButton"));
362+ tryCompare(AccountsService, "hereEnabled", false);
363+ tryCompare(locationActionGroup.location, "state", true);
364+ tryCompare(locationActionGroup.gps, "state", true);
365+ }
366+
367+ function test_locationNope() {
368+ var page = goToPage("locationPage");
369+ var gpsCheck = findChild(page, "gpsCheck");
370+ var hereCheck = findChild(page, "hereCheck");
371+ var nopeCheck = findChild(page, "nopeCheck");
372+
373+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
374+ tryCompare(locationActionGroup.location, "state", false);
375+ tryCompare(locationActionGroup.gps, "state", false);
376+
377+ tap(nopeCheck);
378+ tryCompare(gpsCheck, "checked", false);
379+ tryCompare(hereCheck, "checked", false);
380+ tryCompare(nopeCheck, "checked", true);
381+
382+ tap(findChild(page, "forwardButton"));
383+ tryCompare(AccountsService, "hereEnabled", false);
384+ tryCompare(locationActionGroup.location, "state", false);
385+ tryCompare(locationActionGroup.gps, "state", false);
386+ }
387+
388+ function test_locationHere() {
389+ var page = goToPage("locationPage");
390+ var gpsCheck = findChild(page, "gpsCheck");
391+ var hereCheck = findChild(page, "hereCheck");
392+ var nopeCheck = findChild(page, "nopeCheck");
393+
394+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
395+ tryCompare(locationActionGroup.location, "state", false);
396+ tryCompare(locationActionGroup.gps, "state", false);
397+
398+ // no tap because HERE is the default
399+ tryCompare(gpsCheck, "checked", false);
400+ tryCompare(hereCheck, "checked", true);
401+ tryCompare(nopeCheck, "checked", false);
402+
403+ tap(findChild(page, "forwardButton"));
404+ tryCompare(AccountsService, "hereEnabled", true);
405+ tryCompare(locationActionGroup.location, "state", true);
406+ tryCompare(locationActionGroup.gps, "state", true);
407+ }
408+
409+ function test_locationHereTerms() {
410+ var page = goToPage("locationPage");
411+
412+ var link = findChild(page, "hereTermsLink");
413+
414+ // Test our language lookup code a bit
415+
416+ i18n.language = "fr_FR.UTF-8";
417+ link.linkActivated("not-used");
418+ page = waitForPage("hereTermsPage");
419+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
420+ tap(findChild(page, "backButton"));
421+ waitForPage("locationPage");
422+
423+ i18n.language = "fr_CA";
424+ link.linkActivated("not-used");
425+ page = waitForPage("hereTermsPage");
426+ tryCompare(findChild(page, "termsLabel"), "text", "fr_CA\n");
427+ tap(findChild(page, "backButton"));
428+ waitForPage("locationPage");
429+
430+ i18n.language = "fr_US";
431+ link.linkActivated("not-used");
432+ page = waitForPage("hereTermsPage");
433+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
434+ tap(findChild(page, "backButton"));
435+ waitForPage("locationPage");
436+
437+ i18n.language = "fr.utf8";
438+ link.linkActivated("not-used");
439+ page = waitForPage("hereTermsPage");
440+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
441+ tap(findChild(page, "backButton"));
442+ waitForPage("locationPage");
443+
444+ i18n.language = "es"; // will not be found
445+ link.linkActivated("not-used");
446+ page = waitForPage("hereTermsPage");
447+ tryCompare(findChild(page, "termsLabel"), "text", "en_US\n");
448+
449+ // OK, done with languages, back to actual page
450+
451+ var label = findChild(page, "termsLabel");
452+ label.linkActivated(Qt.resolvedUrl("licenses/en_US.html"));
453+ tryCompare(label, "visible", false);
454+
455+ var webview = findChild(page, "webview");
456+ tryCompare(webview, "visible", true);
457+ tryCompare(webview, "url", Qt.resolvedUrl("licenses/en_US.html"));
458+ tryCompare(webview, "loadProgress", 100);
459+
460+ tap(findChild(page, "backButton"));
461+ waitForPage("hereTermsPage"); // confirm we're on same page
462+ tryCompare(webview, "visible", false);
463+ tryCompare(label, "visible", true);
464+
465+ tap(findChild(page, "backButton"));
466+ waitForPage("locationPage");
467+ }
468+ }
469+}