on xenial help sign in
Add a bunch of tests for wizard
2e474a2Michael Terry
plugins/Wizard/plugin.cpp+1−8
@@ -20,13 +20,6 @@
20
20
21#include <QtQml/qqml.h>
21#include <QtQml/qqml.h>
22
22
23−static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
24−{
25− Q_UNUSED(engine)
26− Q_UNUSED(scriptEngine)
27− return new PageList();
28−}
29−
30static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
23static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
31{
24{
32 Q_UNUSED(engine)
25 Q_UNUSED(engine)
@@ -37,6 +30,6 @@ static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
37void WizardPlugin::registerTypes(const char *uri)
30void WizardPlugin::registerTypes(const char *uri)
38{
31{
39 Q_ASSERT(uri == QLatin1String("Wizard"));
32 Q_ASSERT(uri == QLatin1String("Wizard"));
40− qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
33+ qmlRegisterType<PageList>(uri, 0, 1, "PageList");
41 qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
34 qmlRegisterSingletonType<System>(uri, 0, 1, "System", system_provider);
42}
35}
qml/Wizard/Page.qml+2
@@ -77,6 +77,7 @@ Item {
77
77
78 StackButton {
78 StackButton {
79 id: backButton
79 id: backButton
80+ objectName: "backButton"
80 width: buttonWidth
81 width: buttonWidth
81 anchors {
82 anchors {
82 left: parent.left
83 left: parent.left
@@ -94,6 +95,7 @@ Item {
94
95
95 Loader {
96 Loader {
96 id: forwardButton
97 id: forwardButton
98+ objectName: "forwardButton"
97 width: buttonWidth
99 width: buttonWidth
98 anchors {
100 anchors {
99 right: parent.right
101 right: parent.right
qml/Wizard/Pages.qml+11−4
@@ -29,6 +29,7 @@ Item {
29 ////
29 ////
30
30
31 id: root
31 id: root
32+ objectName: "wizardPages"
32 focus: true
33 focus: true
33 anchors.fill: parent
34 anchors.fill: parent
34
35
@@ -39,6 +40,7 @@ Item {
39
40
40 UbuntuSecurityPrivacyPanel {
41 UbuntuSecurityPrivacyPanel {
41 id: securityPrivacy
42 id: securityPrivacy
43+ objectName: "securityPrivacy"
42 }
44 }
43
45
44 function quitWizard() {
46 function quitWizard() {
@@ -72,21 +74,26 @@ Item {
72 visible: status === Image.Ready
74 visible: status === Image.Ready
73 }
75 }
74
76
77+ PageList {
78+ id: pageList
79+ }
80+
75 PageStack {
81 PageStack {
76 id: pageStack
82 id: pageStack
83+ objectName: "pageStack"
77 anchors.fill: parent
84 anchors.fill: parent
78
85
79 function next() {
86 function next() {
80 // If we've opened any extra (non-main) pages, pop them before
87 // If we've opened any extra (non-main) pages, pop them before
81 // continuing so back button returns to the previous main page.
88 // continuing so back button returns to the previous main page.
82− while (PageList.index < pageStack.depth - 1)
89+ while (pageList.index < pageStack.depth - 1)
83 pop()
90 pop()
84− load(PageList.next())
91+ load(pageList.next())
85 }
92 }
86
93
87 function prev() {
94 function prev() {
88− if (PageList.index >= pageStack.depth - 1)
95+ if (pageList.index >= pageStack.depth - 1)
89− PageList.prev() // update PageList.index, but not for extra pages
96+ pageList.prev() // update pageList.index, but not for extra pages
90 pop()
97 pop()
91 if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
98 if (!currentPage || currentPage.opacity === 0) { // undo skipped pages
92 prev()
99 prev()
qml/Wizard/Pages/10-welcome.qml+4
@@ -22,6 +22,8 @@ import Wizard 0.1
22import ".." as LocalComponents
22import ".." as LocalComponents
23
23
24LocalComponents.Page {
24LocalComponents.Page {
25+ objectName: "languagePage"
26+
25 title: i18n.tr("Hi!")
27 title: i18n.tr("Hi!")
26 forwardButtonSourceComponent: forwardButton
28 forwardButtonSourceComponent: forwardButton
27
29
@@ -57,6 +59,7 @@ LocalComponents.Page {
57
59
58 ComboButton {
60 ComboButton {
59 id: combo
61 id: combo
62+ objectName: "languageCombo"
60 anchors.left: parent.left
63 anchors.left: parent.left
61 anchors.right: parent.right
64 anchors.right: parent.right
62 text: listview.currentItem.text
65 text: listview.currentItem.text
@@ -67,6 +70,7 @@ LocalComponents.Page {
67 model: plugin.languageNames
70 model: plugin.languageNames
68 currentIndex: plugin.currentLanguage
71 currentIndex: plugin.currentLanguage
69 delegate: Standard {
72 delegate: Standard {
73+ objectName: "languageDelegate" + index
70 text: modelData
74 text: modelData
71 onClicked: {
75 onClicked: {
72 listview.currentIndex = index
76 listview.currentIndex = index
qml/Wizard/Pages/20-sim.qml+2
@@ -20,6 +20,8 @@ import Ubuntu.Components 0.1
20import ".." as LocalComponents
20import ".." as LocalComponents
21
21
22LocalComponents.Page {
22LocalComponents.Page {
23+ objectName: "simPage"
24+
23 title: i18n.tr("Add a SIM card and restart your device")
25 title: i18n.tr("Add a SIM card and restart your device")
24 forwardButtonSourceComponent: forwardButton
26 forwardButtonSourceComponent: forwardButton
25
27
qml/Wizard/Pages/30-passwd-type.qml+4
@@ -34,6 +34,8 @@ import ".." as LocalComponents
34
34
35LocalComponents.Page {
35LocalComponents.Page {
36 id: passwdPage
36 id: passwdPage
37+ objectName: "passwdPage"
38+
37 title: i18n.tr("Lock security")
39 title: i18n.tr("Lock security")
38 forwardButtonSourceComponent: forwardButton
40 forwardButtonSourceComponent: forwardButton
39
41
@@ -84,6 +86,8 @@ LocalComponents.Page {
84 selectedIndex: methodToIndex(root.passwordMethod)
86 selectedIndex: methodToIndex(root.passwordMethod)
85
87
86 delegate: OptionSelectorDelegate {
88 delegate: OptionSelectorDelegate {
89+ objectName: "passwdDelegate" + index
90+
87 // use subText because we want the text to be small, and we have no other way to control it
91 // use subText because we want the text to be small, and we have no other way to control it
88 subText: {
92 subText: {
89 var method = indexToMethod(index)
93 var method = indexToMethod(index)
qml/Wizard/Pages/40-wifi.qml+2
@@ -23,6 +23,8 @@ import ".." as LocalComponents
23
23
24LocalComponents.Page {
24LocalComponents.Page {
25 id: wifiPage
25 id: wifiPage
26+ objectName: "wifiPage"
27+
26 title: i18n.tr("Connect to Wi‑Fi")
28 title: i18n.tr("Connect to Wi‑Fi")
27 forwardButtonSourceComponent: forwardButton
29 forwardButtonSourceComponent: forwardButton
28
30
qml/Wizard/Pages/50-location.qml+10−14
@@ -22,34 +22,26 @@ import Ubuntu.Components 1.1
22import ".." as LocalComponents
22import ".." as LocalComponents
23
23
24LocalComponents.Page {
24LocalComponents.Page {
25+ objectName: "locationPage"
26+
25 title: i18n.tr("Location")
27 title: i18n.tr("Location")
26 forwardButtonSourceComponent: forwardButton
28 forwardButtonSourceComponent: forwardButton
27
29
28 property bool pathSet: AccountsService.hereLicensePath !== " " // single space means it's unassigned
30 property bool pathSet: AccountsService.hereLicensePath !== " " // single space means it's unassigned
29− property bool countSet: false
30− skipValid: pathSet && (AccountsService.hereLicensePath === "" || countSet)
31+ skipValid: pathSet && (AccountsService.hereLicensePath === "" || termsModel.count > 0)
31− skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 0)
32+ skip: skipValid && (AccountsService.hereLicensePath === "" || termsModel.count === 2) // no files but . and ..
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− }
42
33
43 FolderListModel {
34 FolderListModel {
44 id: termsModel
35 id: termsModel
45 folder: AccountsService.hereLicensePath
36 folder: AccountsService.hereLicensePath
46 nameFilters: ["*.html"]
37 nameFilters: ["*.html"]
47− showDirs: false
48 showOnlyReadable: true
38 showOnlyReadable: true
39+ showDotAndDotDot: true // so that count == 0 means we're not done scanning yet
49 }
40 }
50
41
51 QMenuModel.QDBusActionGroup {
42 QMenuModel.QDBusActionGroup {
52 id: locationActionGroup
43 id: locationActionGroup
44+ objectName: "locationActionGroup"
53 busType: QMenuModel.DBus.SessionBus
45 busType: QMenuModel.DBus.SessionBus
54 busName: "com.canonical.indicator.location"
46 busName: "com.canonical.indicator.location"
55 objectPath: "/com/canonical/indicator/location"
47 objectPath: "/com/canonical/indicator/location"
@@ -72,6 +64,7 @@ LocalComponents.Page {
72
64
73 LocalComponents.CheckableSetting {
65 LocalComponents.CheckableSetting {
74 id: gpsCheck
66 id: gpsCheck
67+ objectName: "gpsCheck"
75 showDivider: false
68 showDivider: false
76 text: i18n.tr("Using GPS only (less accurate)")
69 text: i18n.tr("Using GPS only (less accurate)")
77 onTriggered: {
70 onTriggered: {
@@ -88,6 +81,7 @@ LocalComponents.Page {
88
81
89 LocalComponents.CheckableSetting {
82 LocalComponents.CheckableSetting {
90 id: hereCheck
83 id: hereCheck
84+ objectName: "hereCheck"
91 showDivider: false
85 showDivider: false
92 text: i18n.tr("Using GPS, anonymized Wi-Fi and cellular network info (recommended)")
86 text: i18n.tr("Using GPS, anonymized Wi-Fi and cellular network info (recommended)")
93 checked: true
87 checked: true
@@ -99,6 +93,7 @@ LocalComponents.Page {
99 }
93 }
100
94
101 Label {
95 Label {
96+ objectName: "hereTermsLink"
102 anchors.left: parent.left
97 anchors.left: parent.left
103 anchors.leftMargin: hereCheck.labelOffset
98 anchors.leftMargin: hereCheck.labelOffset
104 anchors.right: parent.right
99 anchors.right: parent.right
@@ -112,6 +107,7 @@ LocalComponents.Page {
112
107
113 LocalComponents.CheckableSetting {
108 LocalComponents.CheckableSetting {
114 id: nopeCheck
109 id: nopeCheck
110+ objectName: "nopeCheck"
115 showDivider: false
111 showDivider: false
116 text: i18n.tr("Not at all")
112 text: i18n.tr("Not at all")
117 onTriggered: {
113 onTriggered: {
qml/Wizard/Pages/60-reporting.qml+2
@@ -19,6 +19,8 @@ import Ubuntu.Components 0.1
19import ".." as LocalComponents
19import ".." as LocalComponents
20
20
21LocalComponents.Page {
21LocalComponents.Page {
22+ objectName: "reportingPage"
23+
22 title: i18n.tr("Improving your experience")
24 title: i18n.tr("Improving your experience")
23 forwardButtonSourceComponent: forwardButton
25 forwardButtonSourceComponent: forwardButton
24
26
qml/Wizard/Pages/80-finished.qml+2
@@ -19,6 +19,8 @@ import Ubuntu.Components 0.1
19import ".." as LocalComponents
19import ".." as LocalComponents
20
20
21LocalComponents.Page {
21LocalComponents.Page {
22+ objectName: "finishedPage"
23+
22 title: i18n.tr("All done")
24 title: i18n.tr("All done")
23 forwardButtonSourceComponent: forwardButton
25 forwardButtonSourceComponent: forwardButton
24 hasBackButton: false
26 hasBackButton: false
qml/Wizard/Pages/here-terms.qml+4
@@ -22,6 +22,8 @@ import Ubuntu.Web 0.2
22import ".." as LocalComponents
22import ".." as LocalComponents
23
23
24LocalComponents.Page {
24LocalComponents.Page {
25+ objectName: "hereTermsPage"
26+
25 title: i18n.tr("Terms & Conditions")
27 title: i18n.tr("Terms & Conditions")
26 customBack: true
28 customBack: true
27
29
@@ -96,6 +98,7 @@ LocalComponents.Page {
96
98
97 Label {
99 Label {
98 id: termsLabel
100 id: termsLabel
101+ objectName: "termsLabel"
99 anchors.left: parent.left
102 anchors.left: parent.left
100 anchors.right: parent.right
103 anchors.right: parent.right
101 wrapMode: Text.Wrap
104 wrapMode: Text.Wrap
@@ -108,6 +111,7 @@ LocalComponents.Page {
108
111
109 WebView {
112 WebView {
110 id: webview
113 id: webview
114+ objectName: "webview"
111 anchors.left: parent.left
115 anchors.left: parent.left
112 anchors.right: parent.right
116 anchors.right: parent.right
113 height: parent.height
117 height: parent.height
qml/Wizard/Pages/passwd-confirm.qml+2−1
@@ -26,7 +26,8 @@ import "../../Components" as UnityComponents
26 */
26 */
27
27
28LocalComponents.Page {
28LocalComponents.Page {
29− id: passwdSetPage
29+ id: passwdConfirmPage
30+ objectName: "passwdConfirmPage"
30 forwardButtonSourceComponent: forwardButton
31 forwardButtonSourceComponent: forwardButton
31
32
32 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
33 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
qml/Wizard/Pages/passwd-set.qml+1
@@ -27,6 +27,7 @@ import "../../Components" as UnityComponents
27
27
28LocalComponents.Page {
28LocalComponents.Page {
29 id: passwdSetPage
29 id: passwdSetPage
30+ objectName: "passwdSetPage"
30 forwardButtonSourceComponent: forwardButton
31 forwardButtonSourceComponent: forwardButton
31
32
32 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
33 skip: root.passwordMethod === UbuntuSecurityPrivacyPanel.Swipe
tests/mocks/CMakeLists.txt+1
@@ -32,6 +32,7 @@ add_subdirectory(AccountsService)
32add_subdirectory(GSettings.1.0)
32add_subdirectory(GSettings.1.0)
33add_subdirectory(libusermetrics)
33add_subdirectory(libusermetrics)
34add_subdirectory(LightDM)
34add_subdirectory(LightDM)
35+add_subdirectory(MeeGo)
35add_subdirectory(Powerd)
36add_subdirectory(Powerd)
36add_subdirectory(QMenuModel)
37add_subdirectory(QMenuModel)
37add_subdirectory(Ubuntu)
38add_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
21import Ubuntu.Settings.Menus 0.1 as Menus
21import Ubuntu.Settings.Menus 0.1 as Menus
22
22
23QtObject {
23QtObject {
24+ id: actionGroup
24 property int busType
25 property int busType
25 property string busName
26 property string busName
26 property string objectPath
27 property string objectPath
@@ -78,6 +79,17 @@ QtObject {
78 'percent': 0.0
79 'percent': 0.0
79 }
80 }
80 }
81 }
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);
81 default:
93 default:
82 break;
94 break;
83 }
95 }
tests/mocks/Ubuntu/CMakeLists.txt+1
@@ -2,5 +2,6 @@ add_subdirectory(Connectivity)
2add_subdirectory(DownloadDaemonListener)
2add_subdirectory(DownloadDaemonListener)
3add_subdirectory(Payments)
3add_subdirectory(Payments)
4add_subdirectory(SystemImage)
4add_subdirectory(SystemImage)
5+add_subdirectory(SystemSettings)
5add_subdirectory(Telephony)
6add_subdirectory(Telephony)
6add_subdirectory(Thumbnailer)
7add_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)
33 Q_EMIT wizardEnabledChanged();
33 Q_EMIT wizardEnabledChanged();
34}
34}
35
35
36−void MockSystem::updateSessionLanguage(const QString &)
36+void MockSystem::updateSessionLanguage(const QString &locale)
37{
37{
38+ Q_EMIT updateSessionLanguageCalled(locale);
38}
39}
tests/mocks/Wizard/MockSystem.h+1
@@ -36,6 +36,7 @@ public Q_SLOTS:
36
36
37Q_SIGNALS:
37Q_SIGNALS:
38 void wizardEnabledChanged();
38 void wizardEnabledChanged();
39+ void updateSessionLanguageCalled(const QString &locale); // only in mock
39
40
40private:
41private:
41 Q_DISABLE_COPY(MockSystem)
42 Q_DISABLE_COPY(MockSystem)
tests/mocks/Wizard/mockplugin.cpp+1−8
@@ -20,13 +20,6 @@
20
20
21#include <QtQml/qqml.h>
21#include <QtQml/qqml.h>
22
22
23−static QObject *pagelist_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
24−{
25− Q_UNUSED(engine)
26− Q_UNUSED(scriptEngine)
27− return new PageList();
28−}
29−
30static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
23static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
31{
24{
32 Q_UNUSED(engine)
25 Q_UNUSED(engine)
@@ -37,6 +30,6 @@ static QObject *system_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
37void MockWizardPlugin::registerTypes(const char *uri)
30void MockWizardPlugin::registerTypes(const char *uri)
38{
31{
39 Q_ASSERT(uri == QLatin1String("Wizard"));
32 Q_ASSERT(uri == QLatin1String("Wizard"));
40− qmlRegisterSingletonType<PageList>(uri, 0, 1, "PageList", pagelist_provider);
33+ qmlRegisterType<PageList>(uri, 0, 1, "PageList");
41 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", system_provider);
34 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", system_provider);
42}
35}
tests/plugins/Wizard/CMakeLists.txt+9−3
@@ -3,10 +3,16 @@ include_directories(
3 ${CMAKE_SOURCE_DIR}/plugins/Wizard
3 ${CMAKE_SOURCE_DIR}/plugins/Wizard
4)
4)
5
5
6−add_executable(tst-pagelist
6+add_executable(tst-wizard-pagelist
7 tst_pagelist.cpp
7 tst_pagelist.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
9)
9)
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)
11
12
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)
12−add_test(NAME pagelisttest COMMAND env UNITY_TEST_ENV=1 ${CMAKE_CURRENT_BINARY_DIR}/tst-pagelist)
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
87add_qml_test(Stages SurfaceContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
87add_qml_test(Stages SurfaceContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
88add_qml_test(Stages SessionContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
88add_qml_test(Stages SessionContainer ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
89add_qml_test(Stages Splash)
89add_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+}