@@ -0,0 +1,479 @@
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+
174+ // For some reason, the delegate *sometimes* (like 1 in 10 maybe)
175+ // needs more time before it can process a tap() call. I can't
176+ // find a rhyme or reason, its properties all seem the same in
177+ // cases where it works and does not. This failure to receive a
178+ // tap() call below does *not* happen when running in xvfb, so
179+ // jenkins is unaffected (and we don't have to worry about 100 not
180+ // being enough time in its slow environment). This wait() call is
181+ // just to help local runs not trip up.
182+ wait(100);
183+ tap(findChild(page, "languageDelegate1"));
184+
185+ tryCompare(i18n, "language", "fr");
186+ tap(findChild(page, "forwardButton"));
187+ tryCompare(updateSessionLanguageSpy, "count", 1);
188+ compare(updateSessionLanguageSpy.signalArguments[0][0], "fr");
189+ }
190+
191+ function test_languageNoChange() {
192+ goToPage("simPage"); // one past language page
193+ compare(updateSessionLanguageSpy.count, 0);
194+ }
195+
196+ function test_simUnavailableSkip() {
197+ MockQOfono.available = false;
198+ goToPage("passwdPage", true);
199+ }
200+
201+ function test_simNoModemsSkip() {
202+ MockQOfono.setModems([], []);
203+ goToPage("passwdPage", true);
204+ }
205+
206+ function test_simFirstSkip() {
207+ MockQOfono.setModems(["a", "b"], [true, false]);
208+ goToPage("passwdPage", true);
209+ }
210+
211+ function test_simSecondSkip() {
212+ MockQOfono.setModems(["a", "b"], [false, true]);
213+ goToPage("passwdPage", true);
214+ }
215+
216+ function test_simBothSkip() {
217+ MockQOfono.setModems(["a", "b"], [true, true]);
218+ goToPage("passwdPage", true);
219+ }
220+
221+ function enterPasscode(passcode) {
222+ for (var i = 0; i < passcode.length; ++i) {
223+ var character = passcode.charAt(i);
224+ var button = findChild(wizard, "pinPadButton" + character);
225+ tap(button);
226+ }
227+ }
228+
229+ function test_passwdPasscode() {
230+ var page = goToPage("passwdPage");
231+
232+ tap(findChild(page, "forwardButton"));
233+ page = waitForPage("passwdSetPage");
234+
235+ enterPasscode("1111");
236+ page = waitForPage("passwdConfirmPage");
237+
238+ // make sure we go back to 'set' page not 'type' page
239+ tap(findChild(page, "backButton"));
240+ page = waitForPage("passwdSetPage");
241+
242+ enterPasscode("1111");
243+ page = waitForPage("passwdConfirmPage");
244+
245+ enterPasscode("1112");
246+ var error = findChild(page, "wrongNoticeLabel");
247+ tryCompareFunction(function() { return error.text !== ""; }, true);
248+
249+ enterPasscode("1111");
250+ page = waitForPage("wifiPage");
251+
252+ // now finish up
253+ tap(findChild(page, "forwardButton"));
254+ page = waitForPage("locationPage");
255+ tap(findChild(page, "forwardButton"));
256+ page = waitForPage("reportingPage");
257+ tap(findChild(page, "forwardButton"));
258+ page = waitForPage("finishedPage");
259+ tap(findChild(page, "forwardButton"));
260+
261+ tryCompare(setSecuritySpy, "count", 1);
262+ compare(setSecuritySpy.signalArguments[0][0], "");
263+ compare(setSecuritySpy.signalArguments[0][1], "1111");
264+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Passcode);
265+ }
266+
267+ function test_passwdPassphrase() {
268+ var page = goToPage("passwdPage");
269+ tap(findChild(page, "passwdDelegate2"));
270+
271+ tap(findChild(page, "forwardButton"));
272+ page = waitForPage("passwdSetPage");
273+
274+ typeString("aaa");
275+ var continueButton = findChild(page, "forwardButton");
276+ tryCompare(continueButton.item, "enabled", false);
277+ keyClick(Qt.Key_Enter);
278+ var error = findChild(page, "wrongNoticeLabel");
279+ tryCompareFunction(function() { return error.text !== ""; }, true);
280+
281+ typeString("aaaa");
282+ tap(continueButton);
283+ page = waitForPage("passwdConfirmPage");
284+
285+ // make sure we go back to 'set' page not 'type' page
286+ var back = findChild(page, "backButton");
287+ tap(back);
288+ page = waitForPage("passwdSetPage");
289+
290+ typeString("aaaa");
291+ keyClick(Qt.Key_Enter);
292+ page = waitForPage("passwdConfirmPage");
293+
294+ continueButton = findChild(page, "forwardButton");
295+ typeString("aaab");
296+ tryCompare(continueButton.item, "enabled", false);
297+ keyClick(Qt.Key_Enter);
298+ var error = findChild(page, "wrongNoticeLabel");
299+ tryCompareFunction(function() { return error.text !== ""; }, true);
300+
301+ typeString("aaaa");
302+ tap(continueButton);
303+ page = waitForPage("wifiPage");
304+
305+ // now finish up
306+ tap(findChild(page, "forwardButton"));
307+ page = waitForPage("locationPage");
308+ tap(findChild(page, "forwardButton"));
309+ page = waitForPage("reportingPage");
310+ tap(findChild(page, "forwardButton"));
311+ page = waitForPage("finishedPage");
312+ tap(findChild(page, "forwardButton"));
313+
314+ tryCompare(setSecuritySpy, "count", 1);
315+ compare(setSecuritySpy.signalArguments[0][0], "");
316+ compare(setSecuritySpy.signalArguments[0][1], "aaaa");
317+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Passphrase);
318+ }
319+
320+ function test_passwdSwipe() {
321+ goToPage(null);
322+
323+ tryCompare(setSecuritySpy, "count", 1);
324+ compare(setSecuritySpy.signalArguments[0][0], "");
325+ compare(setSecuritySpy.signalArguments[0][1], "");
326+ compare(setSecuritySpy.signalArguments[0][2], UbuntuSecurityPrivacyPanel.Swipe);
327+ }
328+
329+ function test_locationSkipNoPath() {
330+ AccountsService.hereLicensePath = "";
331+ goToPage("reportingPage", false, true);
332+ }
333+
334+ function test_locationSkipNoFiles() {
335+ AccountsService.hereLicensePath = Qt.resolvedUrl("nolicenses");
336+ goToPage("reportingPage", false, true);
337+ }
338+
339+ function test_locationWaitOnPath() {
340+ AccountsService.hereLicensePath = " "; // means we're still getting the path from dbus
341+
342+ var page = goToPage("wifiPage");
343+
344+ var pages = findChild(wizard, "wizardPages");
345+ var stack = findChild(pages, "pageStack");
346+ tap(findChild(page, "forwardButton"));
347+ // don't simply call tryCompare here, because stack.currentPage will be swapped out itself
348+ tryCompareFunction(function() { return stack.currentPage.objectName; }, "locationPage");
349+ compare(stack.currentPage.enabled, false);
350+ compare(stack.currentPage.skipValid, false);
351+
352+ AccountsService.hereLicensePath = "";
353+ waitForPage("reportingPage");
354+ }
355+
356+ function test_locationGpsOnly() {
357+ var page = goToPage("locationPage");
358+ var gpsCheck = findChild(page, "gpsCheck");
359+ var hereCheck = findChild(page, "hereCheck");
360+ var nopeCheck = findChild(page, "nopeCheck");
361+
362+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
363+ tryCompare(locationActionGroup.location, "state", false);
364+ tryCompare(locationActionGroup.gps, "state", false);
365+
366+ tap(gpsCheck);
367+ tryCompare(gpsCheck, "checked", true);
368+ tryCompare(hereCheck, "checked", false);
369+ tryCompare(nopeCheck, "checked", false);
370+
371+ tap(findChild(page, "forwardButton"));
372+ tryCompare(AccountsService, "hereEnabled", false);
373+ tryCompare(locationActionGroup.location, "state", true);
374+ tryCompare(locationActionGroup.gps, "state", true);
375+ }
376+
377+ function test_locationNope() {
378+ var page = goToPage("locationPage");
379+ var gpsCheck = findChild(page, "gpsCheck");
380+ var hereCheck = findChild(page, "hereCheck");
381+ var nopeCheck = findChild(page, "nopeCheck");
382+
383+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
384+ tryCompare(locationActionGroup.location, "state", false);
385+ tryCompare(locationActionGroup.gps, "state", false);
386+
387+ tap(nopeCheck);
388+ tryCompare(gpsCheck, "checked", false);
389+ tryCompare(hereCheck, "checked", false);
390+ tryCompare(nopeCheck, "checked", true);
391+
392+ tap(findChild(page, "forwardButton"));
393+ tryCompare(AccountsService, "hereEnabled", false);
394+ tryCompare(locationActionGroup.location, "state", false);
395+ tryCompare(locationActionGroup.gps, "state", false);
396+ }
397+
398+ function test_locationHere() {
399+ var page = goToPage("locationPage");
400+ var gpsCheck = findChild(page, "gpsCheck");
401+ var hereCheck = findChild(page, "hereCheck");
402+ var nopeCheck = findChild(page, "nopeCheck");
403+
404+ var locationActionGroup = findInvisibleChild(page, "locationActionGroup");
405+ tryCompare(locationActionGroup.location, "state", false);
406+ tryCompare(locationActionGroup.gps, "state", false);
407+
408+ // no tap because HERE is the default
409+ tryCompare(gpsCheck, "checked", false);
410+ tryCompare(hereCheck, "checked", true);
411+ tryCompare(nopeCheck, "checked", false);
412+
413+ tap(findChild(page, "forwardButton"));
414+ tryCompare(AccountsService, "hereEnabled", true);
415+ tryCompare(locationActionGroup.location, "state", true);
416+ tryCompare(locationActionGroup.gps, "state", true);
417+ }
418+
419+ function test_locationHereTerms() {
420+ var page = goToPage("locationPage");
421+
422+ var link = findChild(page, "hereTermsLink");
423+
424+ // Test our language lookup code a bit
425+
426+ i18n.language = "fr_FR.UTF-8";
427+ link.linkActivated("not-used");
428+ page = waitForPage("hereTermsPage");
429+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
430+ tap(findChild(page, "backButton"));
431+ waitForPage("locationPage");
432+
433+ i18n.language = "fr_CA";
434+ link.linkActivated("not-used");
435+ page = waitForPage("hereTermsPage");
436+ tryCompare(findChild(page, "termsLabel"), "text", "fr_CA\n");
437+ tap(findChild(page, "backButton"));
438+ waitForPage("locationPage");
439+
440+ i18n.language = "fr_US";
441+ link.linkActivated("not-used");
442+ page = waitForPage("hereTermsPage");
443+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
444+ tap(findChild(page, "backButton"));
445+ waitForPage("locationPage");
446+
447+ i18n.language = "fr.utf8";
448+ link.linkActivated("not-used");
449+ page = waitForPage("hereTermsPage");
450+ tryCompare(findChild(page, "termsLabel"), "text", "fr_FR\n");
451+ tap(findChild(page, "backButton"));
452+ waitForPage("locationPage");
453+
454+ i18n.language = "es"; // will not be found
455+ link.linkActivated("not-used");
456+ page = waitForPage("hereTermsPage");
457+ tryCompare(findChild(page, "termsLabel"), "text", "en_US\n");
458+
459+ // OK, done with languages, back to actual page
460+
461+ var label = findChild(page, "termsLabel");
462+ label.linkActivated(Qt.resolvedUrl("licenses/en_US.html"));
463+ tryCompare(label, "visible", false);
464+
465+ var webview = findChild(page, "webview");
466+ tryCompare(webview, "visible", true);
467+ tryCompare(webview, "url", Qt.resolvedUrl("licenses/en_US.html"));
468+ tryCompare(webview, "loadProgress", 100);
469+
470+ tap(findChild(page, "backButton"));
471+ waitForPage("hereTermsPage"); // confirm we're on same page
472+ tryCompare(webview, "visible", false);
473+ tryCompare(label, "visible", true);
474+
475+ tap(findChild(page, "backButton"));
476+ waitForPage("locationPage");
477+ }
478+ }
479+}