Merge lp:~abreu-alexandre/webbrowser-app/webapp-homepage into lp:webbrowser-app

Proposed by Alexandre Abreu
Status: Superseded
Proposed branch: lp:~abreu-alexandre/webbrowser-app/webapp-homepage
Merge into: lp:webbrowser-app
Diff against target: 872 lines (+288/-103)
16 files modified
po/webbrowser-app.pot (+14/-14)
src/app/webcontainer/Chrome.qml (+1/-1)
src/app/webcontainer/WebApp.qml (+4/-12)
src/app/webcontainer/WebViewImplOxide.qml (+34/-20)
src/app/webcontainer/WebViewImplWebkit.qml (+4/-1)
src/app/webcontainer/WebappContainerWebview.qml (+5/-2)
src/app/webcontainer/url-pattern-utils.cpp (+28/-7)
src/app/webcontainer/url-pattern-utils.h (+2/-1)
src/app/webcontainer/webapp-container.cpp (+24/-13)
src/app/webcontainer/webapp-container.h (+1/-1)
src/app/webcontainer/webapp-container.qml (+24/-9)
tests/autopilot/webapp_container/tests/__init__.py (+43/-5)
tests/autopilot/webapp_container/tests/fake_servers.py (+28/-8)
tests/autopilot/webapp_container/tests/test_app_launch.py (+1/-1)
tests/autopilot/webapp_container/tests/test_redirection_pattern.py (+59/-0)
tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp (+16/-8)
To merge this branch: bzr merge lp:~abreu-alexandre/webbrowser-app/webapp-homepage
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Olivier Tilloy Approve
David Barth (community) Approve
Review via email: mp+237456@code.launchpad.net

Commit message

Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.

Description of the change

Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
760. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

Revision history for this message
David Barth (dbarth) :
review: Approve
Revision history for this message
Olivier Tilloy (osomon) wrote :

This changeset does much more than what it says on the tin. Please update the commit message to make it clear that this introduces StateSaver support for the webapp container. Also, wasn’t there a bug report to track the introduction of StateSaver? If so, please link it to the MR, and if not please file one and link it.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

Given that updateBrowserUrl() is called only in one place, I don’t think factoring it out in its own function is useful. But it doesn’t harm either, I guess.

Code changes look good, not functionally tested.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:753
http://jenkins.qa.ubuntu.com/job/webbrowser-app-ci/1177/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/5811/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/4037
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-amd64-ci/376
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-armhf-ci/376
        deb: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-armhf-ci/376/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-i386-ci/376
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/5466/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/7063
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/7063/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/14503
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/3404
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4366
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4366/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/webbrowser-app-ci/1177/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:753
http://jenkins.qa.ubuntu.com/job/webbrowser-app-ci/1179/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/5825/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/4042
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-amd64-ci/378
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-armhf-ci/378
        deb: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-armhf-ci/378/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/webbrowser-app-utopic-i386-ci/378
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/5479/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/7077
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/7077/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/14521
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/3409
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4371
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/4371/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/webbrowser-app-ci/1179/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
761. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

762. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

763. By Michael Sheldon

Detect 7 digital album downloads and request that they get unzipped by download manager. Fixes: 1365993
Approved by: PS Jenkins bot, Olivier Tilloy

764. By PS Jenkins bot

Releasing 0.23+14.10.20141015.1-0ubuntu1

765. By PS Jenkins bot

Resync trunk

766. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

767. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

768. By Olivier Tilloy

Fix the override mechanism for navigator.userAgent,
and add UA override rules for HSBC’s Brazilian mobile site and ESPN’s mobile site. Fixes: 1316259, 1380657
Approved by: Bill Filler, PS Jenkins bot

769. By PS Jenkins bot

Releasing 0.23+14.10.20141028~rtm-0ubuntu1

770. By PS Jenkins bot

Resync trunk

771. By Riccardo Padovani

Fixed #1378975 - Fast double click on menu button opens menu twice Fixes: 1378975
Approved by: Olivier Tilloy

772. By Riccardo Padovani

Updated the README
Approved by: Olivier Tilloy

773. By Jean-Francois Moy

Twitter User Script - Hide the prompt to download the Android application. Fixes: 1352789, 1377268, 1378008
Approved by: Alexandre Abreu, Olivier Tilloy

774. By PS Jenkins bot

Fix the override mechanism for navigator.userAgent,
and add UA override rules for HSBC’s Brazilian mobile site and ESPN’s mobile site. Fixes: 1316259, 1380657
Approved by: Bill Filler, PS Jenkins bot

775. By Olivier Tilloy

Prevent the browser from trying to download embedded flash applications. Fixes: 1379806
Approved by: Alexandre Abreu

776. By Olivier Tilloy

Fix a harmless compilation warning found by clang (non-literal-null-conversion).

777. By Olivier Tilloy

Update UITK autopilot test imports. Fixes: 1386276
Approved by: Zsombor Egri, PS Jenkins bot

778. By PS Jenkins bot

Releasing 0.23+15.04.20141029.1-0ubuntu1

779. By Alexandre Abreu

Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.

Unmerged revisions

779. By Alexandre Abreu

Webapp homepage only considered if no command line override is provided. Add support for StateSaver url tracking.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'po/webbrowser-app.pot'
--- po/webbrowser-app.pot 2014-10-03 14:41:14 +0000
+++ po/webbrowser-app.pot 2014-10-20 22:12:22 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: webbrowser-app\n"9"Project-Id-Version: webbrowser-app\n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2014-09-22 14:59+0100\n"11"POT-Creation-Date: 2014-10-20 17:24-0400\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -117,7 +117,7 @@
117msgstr ""117msgstr ""
118118
119#: src/app/GeolocationPermissionRequest.qml:29119#: src/app/GeolocationPermissionRequest.qml:29
120#: src/app/webcontainer/WebViewImplWebkit.qml:65120#: src/app/webcontainer/WebViewImplWebkit.qml:68
121msgid "This page wants to know your device’s location."121msgid "This page wants to know your device’s location."
122msgstr ""122msgstr ""
123123
@@ -406,19 +406,19 @@
406msgid "search or enter an address"406msgid "search or enter an address"
407msgstr ""407msgstr ""
408408
409#: src/app/webbrowser/Browser.qml:179409#: src/app/webbrowser/Browser.qml:190
410msgid "Share"410msgid "Share"
411msgstr ""411msgstr ""
412412
413#: src/app/webbrowser/Browser.qml:193413#: src/app/webbrowser/Browser.qml:204
414msgid "History"414msgid "History"
415msgstr ""415msgstr ""
416416
417#: src/app/webbrowser/Browser.qml:200417#: src/app/webbrowser/Browser.qml:211
418msgid "Open tabs"418msgid "Open tabs"
419msgstr ""419msgstr ""
420420
421#: src/app/webbrowser/Browser.qml:206 src/app/webbrowser/TabsView.qml:57421#: src/app/webbrowser/Browser.qml:217 src/app/webbrowser/TabsView.qml:57
422msgid "New tab"422msgid "New tab"
423msgstr ""423msgstr ""
424424
@@ -445,19 +445,19 @@
445msgid "Done"445msgid "Done"
446msgstr ""446msgstr ""
447447
448#: src/app/webbrowser/HistoryView.qml:113448#: src/app/webbrowser/HistoryView.qml:112
449msgid "Clear"449msgid "Clear"
450msgstr ""450msgstr ""
451451
452#: src/app/webbrowser/HistoryView.qml:127452#: src/app/webbrowser/HistoryView.qml:126
453msgid "Delete all history?"453msgid "Delete all history?"
454msgstr ""454msgstr ""
455455
456#: src/app/webbrowser/HistoryView.qml:130456#: src/app/webbrowser/HistoryView.qml:129
457msgid "Yes"457msgid "Yes"
458msgstr ""458msgstr ""
459459
460#: src/app/webbrowser/HistoryView.qml:139460#: src/app/webbrowser/HistoryView.qml:138
461msgid "No"461msgid "No"
462msgstr ""462msgstr ""
463463
@@ -481,7 +481,7 @@
481msgid "Tap to view"481msgid "Tap to view"
482msgstr ""482msgstr ""
483483
484#: src/app/webbrowser/TabsView.qml:115484#: src/app/webbrowser/TabsView.qml:114
485msgid "Add"485msgid "Add"
486msgstr ""486msgstr ""
487487
@@ -497,15 +497,15 @@
497msgid "Ubuntu Web Browser"497msgid "Ubuntu Web Browser"
498msgstr ""498msgstr ""
499499
500#: src/app/webcontainer/AccountsLoginPage.qml:87500#: src/app/webcontainer/AccountsLoginPage.qml:91
501msgid "No local account found for "501msgid "No local account found for "
502msgstr ""502msgstr ""
503503
504#: src/app/webcontainer/AccountsLoginPage.qml:92504#: src/app/webcontainer/AccountsLoginPage.qml:96
505msgid "Skip account creation step"505msgid "Skip account creation step"
506msgstr ""506msgstr ""
507507
508#: src/app/webcontainer/AccountsLoginPage.qml:141508#: src/app/webcontainer/AccountsLoginPage.qml:145
509msgid "Add account"509msgid "Add account"
510msgstr ""510msgstr ""
511511
512512
=== modified file 'src/app/webcontainer/Chrome.qml'
--- src/app/webcontainer/Chrome.qml 2014-07-29 21:51:07 +0000
+++ src/app/webcontainer/Chrome.qml 2014-10-20 22:12:22 +0000
@@ -82,7 +82,7 @@
8282
83 Favicon {83 Favicon {
84 anchors.centerIn: parent84 anchors.centerIn: parent
85 source: chrome.webview.icon85 source: chrome.webview ? chrome.webview.icon : null
86 }86 }
87 }87 }
8888
8989
=== modified file 'src/app/webcontainer/WebApp.qml'
--- src/app/webcontainer/WebApp.qml 2014-10-03 14:41:14 +0000
+++ src/app/webcontainer/WebApp.qml 2014-10-20 22:12:22 +0000
@@ -36,9 +36,10 @@
36 property alias oxide: webview.withOxide36 property alias oxide: webview.withOxide
37 property alias webappName: webview.webappName37 property alias webappName: webview.webappName
38 property alias webappUrlPatterns: webview.webappUrlPatterns38 property alias webappUrlPatterns: webview.webappUrlPatterns
39 property alias popupRedirectionUrlPrefix: webview.popupRedirectionUrlPrefix39 property alias popupRedirectionUrlPrefixPattern: webview.popupRedirectionUrlPrefixPattern
40 property alias webviewOverrideFile: webview.webviewOverrideFile40 property alias webviewOverrideFile: webview.webviewOverrideFile
41 property string localUserAgentOverride: ""41 property string localUserAgentOverride: ""
42 property alias blockOpenExternalUrls: webview.blockOpenExternalUrls
4243
43 property bool backForwardButtonsVisible: false44 property bool backForwardButtonsVisible: false
44 property bool chromeVisible: false45 property bool chromeVisible: false
@@ -69,10 +70,12 @@
69 }70 }
7071
71 Item {72 Item {
73 id: webviewContainer
72 anchors.fill: parent74 anchors.fill: parent
7375
74 WebappContainerWebview {76 WebappContainerWebview {
75 id: webview77 id: webview
78 objectName: "webview"
7679
77 anchors {80 anchors {
78 left: parent.left81 left: parent.left
@@ -179,15 +182,4 @@
179 actionsContext: actionManager.globalContext182 actionsContext: actionManager.globalContext
180 model: UnityWebApps.UnityWebappsAppModel { searchPath: webappModelSearchPath }183 model: UnityWebApps.UnityWebappsAppModel { searchPath: webappModelSearchPath }
181 }184 }
182
183 function isValidContainedUrl(url) {
184 if (!url || url.length === 0 || url === 'about:blank') {
185 return false
186 }
187 if (popupRedirectionUrlPrefix.length !== 0
188 && url.indexOf(popupRedirectionUrlPrefix) === 0) {
189 return false
190 }
191 return true
192 }
193}185}
194186
=== modified file 'src/app/webcontainer/WebViewImplOxide.qml'
--- src/app/webcontainer/WebViewImplOxide.qml 2014-08-19 08:42:30 +0000
+++ src/app/webcontainer/WebViewImplOxide.qml 2014-10-20 22:12:22 +0000
@@ -33,7 +33,16 @@
33 property string webappName: ""33 property string webappName: ""
34 property string localUserAgentOverride: ""34 property string localUserAgentOverride: ""
35 property var webappUrlPatterns: null35 property var webappUrlPatterns: null
36 property string popupRedirectionUrlPrefix: ""36 property string popupRedirectionUrlPrefixPattern: ""
37
38 // Mostly used for testing & avoid external urls to
39 // "leak" in the default browser
40 property bool blockOpenExternalUrls: false
41
42 // Those signals are used for testing purposes to externally
43 // track down the various internal logic & steps of a popup lifecycle.
44 signal openExternalUrlTriggered(string url)
45 signal gotRedirectionUrl(string url)
3746
38 currentWebview: webview47 currentWebview: webview
3948
@@ -48,6 +57,9 @@
48 }57 }
49 }58 }
5059
60 StateSaver.properties: "url"
61 StateSaver.enabled: true
62
51 function shouldOpenPopupsInDefaultBrowser() {63 function shouldOpenPopupsInDefaultBrowser() {
52 return formFactor !== "desktop";64 return formFactor !== "desktop";
53 }65 }
@@ -70,6 +82,13 @@
70 disposition === Oxide.NavigationRequest.DispositionNewForegroundTab;82 disposition === Oxide.NavigationRequest.DispositionNewForegroundTab;
71 }83 }
7284
85 function openUrlExternally(url) {
86 webview.openExternalUrlTriggered(url)
87 if (! webview.blockOpenExternalUrls) {
88 Qt.openUrlExternally(url)
89 }
90 }
91
73 function shouldAllowNavigationTo(url) {92 function shouldAllowNavigationTo(url) {
74 // The list of url patterns defined by the webapp takes precedence over command line93 // The list of url patterns defined by the webapp takes precedence over command line
75 if (isRunningAsANamedWebapp()) {94 if (isRunningAsANamedWebapp()) {
@@ -113,36 +132,31 @@
113 return132 return
114 }133 }
115134
135 var redirectionPatternMatch = url.match(popupRedirectionUrlPrefixPattern);
116 var isRedirectionUrl =136 var isRedirectionUrl =
117 popupRedirectionUrlPrefix.length !== 0137 popupRedirectionUrlPrefixPattern
118 && url.indexOf(popupRedirectionUrlPrefix) === 0;138 && redirectionPatternMatch
119139 && redirectionPatternMatch.length >= 2;
120 var targetUrl = url;140 var targetUrl = url;
121 if (isRedirectionUrl) {141 if (isRedirectionUrl) {
122 // Extract the target URL.142 // Assume that the first group is the matching one
123 targetUrl = url.slice(popupRedirectionUrlPrefix.length);143 targetUrl = redirectionPatternMatch[1];
124 // Quick fix for http://pad.lv/1358622 (trim trailing parameters).144 console.debug("Got a redirection URL with target URL: " + targetUrl)
125 // A proper solution would probably involve regexps instead of a145 targetUrl = decodeURIComponent(targetUrl)
126 // simple redirection prefix.146 gotRedirectionUrl(targetUrl)
127 var extraParams = targetUrl.indexOf("&");
128 if (extraParams !== -1) {
129 targetUrl = targetUrl.slice(0, extraParams);
130 }
131 // Decode it.
132 targetUrl = decodeURIComponent(targetUrl);
133 }147 }
134148
135 if (webview.shouldAllowNavigationTo(targetUrl)) {149 if (webview.shouldAllowNavigationTo(targetUrl)) {
136 console.debug('Redirecting popup browsing ' + targetUrl + ' in the current container window.')150 console.debug('Redirecting popup browsing ' + targetUrl + ' in the current container window.')
137 request.action = Oxide.NavigationRequest.ActionReject151 request.action = Oxide.NavigationRequest.ActionReject
138 webappContainerHelper.browseToUrlRequested(webview, url.slice(url.indexOf(popupRedirectionUrlPrefix)))152 webappContainerHelper.browseToUrlRequested(webview, targetUrl)
139 return153 return
140 }154 }
141155
142 if (shouldOpenPopupsInDefaultBrowser()) {156 if (shouldOpenPopupsInDefaultBrowser()) {
143 console.debug('Opening popup window ' + targetUrl + ' in the browser window.')157 console.debug('Opening popup window ' + targetUrl + ' in the browser window.')
144 request.action = Oxide.NavigationRequest.ActionReject158 request.action = Oxide.NavigationRequest.ActionReject
145 Qt.openUrlExternally(targetUrl)159 openUrlExternally(targetUrl)
146 return;160 return;
147 }161 }
148 return162 return
@@ -179,7 +193,7 @@
179193
180 if (request.action === Oxide.NavigationRequest.ActionReject) {194 if (request.action === Oxide.NavigationRequest.ActionReject) {
181 console.debug('Opening: ' + url + ' in the browser window.')195 console.debug('Opening: ' + url + ' in the browser window.')
182 Qt.openUrlExternally(url)196 openUrlExternally(url)
183 }197 }
184 }198 }
185199
@@ -203,7 +217,7 @@
203 if ( ! isNewForegroundWebViewDisposition(request.disposition) &&217 if ( ! isNewForegroundWebViewDisposition(request.disposition) &&
204 ! webview.shouldAllowNavigationTo(url)) {218 ! webview.shouldAllowNavigationTo(url)) {
205 request.action = Oxide.NavigationRequest.ActionReject219 request.action = Oxide.NavigationRequest.ActionReject
206 Qt.openUrlExternally(url);220 openUrlExternally(url);
207 popup.close()221 popup.close()
208 return;222 return;
209 }223 }
@@ -233,7 +247,7 @@
233 return;247 return;
234248
235 if (_url != 'about:blank' && ! webview.shouldAllowNavigationTo(_url)) {249 if (_url != 'about:blank' && ! webview.shouldAllowNavigationTo(_url)) {
236 Qt.openUrlExternally(_url);250 openUrlExternally(_url);
237 popup.close()251 popup.close()
238 }252 }
239 }253 }
240254
=== modified file 'src/app/webcontainer/WebViewImplWebkit.qml'
--- src/app/webcontainer/WebViewImplWebkit.qml 2014-07-29 21:51:07 +0000
+++ src/app/webcontainer/WebViewImplWebkit.qml 2014-10-20 22:12:22 +0000
@@ -34,7 +34,7 @@
34 property string webappName: ""34 property string webappName: ""
35 property var webappUrlPatterns: null35 property var webappUrlPatterns: null
36 property string localUserAgentOverride: ""36 property string localUserAgentOverride: ""
37 property string popupRedirectionUrlPrefix: ""37 property string popupRedirectionUrlPrefixPattern: ""
3838
39 function getUAString() {39 function getUAString() {
40 return webview.localUserAgentOverride.length === 0 ? undefined : webview.localUserAgentOverride40 return webview.localUserAgentOverride.length === 0 ? undefined : webview.localUserAgentOverride
@@ -53,6 +53,9 @@
53 }53 }
54 }54 }
5555
56 StateSaver.properties: "url"
57 StateSaver.enabled: true
58
56 property bool lastLoadFailed: false59 property bool lastLoadFailed: false
57 onLoadingChanged: {60 onLoadingChanged: {
58 lastLoadFailed = (loadRequest.status === WebView.LoadFailedStatus)61 lastLoadFailed = (loadRequest.status === WebView.LoadFailedStatus)
5962
=== modified file 'src/app/webcontainer/WebappContainerWebview.qml'
--- src/app/webcontainer/WebappContainerWebview.qml 2014-09-02 06:29:12 +0000
+++ src/app/webcontainer/WebappContainerWebview.qml 2014-10-20 22:12:22 +0000
@@ -33,11 +33,13 @@
33 property var currentWebview: webappContainerWebViewLoader.item33 property var currentWebview: webappContainerWebViewLoader.item
34 property var webappUrlPatterns34 property var webappUrlPatterns
35 property string localUserAgentOverride: ""35 property string localUserAgentOverride: ""
36 property string popupRedirectionUrlPrefix: ""36 property string popupRedirectionUrlPrefixPattern: ""
37 property url webviewOverrideFile: ""37 property url webviewOverrideFile: ""
38 property bool blockOpenExternalUrls: false
3839
39 Loader {40 Loader {
40 id: webappContainerWebViewLoader41 id: webappContainerWebViewLoader
42 objectName: "containerWebviewLoader"
41 anchors.fill: parent43 anchors.fill: parent
42 asynchronous: true44 asynchronous: true
43 }45 }
@@ -62,7 +64,8 @@
62 , webappName: containerWebview.webappName64 , webappName: containerWebview.webappName
63 , webappUrlPatterns: containerWebview.webappUrlPatterns65 , webappUrlPatterns: containerWebview.webappUrlPatterns
64 , developerExtrasEnabled: containerWebview.developerExtrasEnabled66 , developerExtrasEnabled: containerWebview.developerExtrasEnabled
65 , popupRedirectionUrlPrefix: containerWebview.popupRedirectionUrlPrefix})67 , popupRedirectionUrlPrefixPattern: containerWebview.popupRedirectionUrlPrefixPattern
68 , blockOpenExternalUrls: containerWebview.blockOpenExternalUrls})
66 }69 }
67}70}
6871
6972
=== modified file 'src/app/webcontainer/url-pattern-utils.cpp'
--- src/app/webcontainer/url-pattern-utils.cpp 2014-09-05 20:14:53 +0000
+++ src/app/webcontainer/url-pattern-utils.cpp 2014-10-20 22:12:22 +0000
@@ -21,6 +21,8 @@
21#include <QtCore/QRegularExpression>21#include <QtCore/QRegularExpression>
22#include <QDebug>22#include <QDebug>
2323
24namespace
25{
2426
25/**27/**
26 * Tests for the validity of a given webapp url pattern. It follows28 * Tests for the validity of a given webapp url pattern. It follows
@@ -35,7 +37,7 @@
35 * @param pattern pattern that is to be tested for validity37 * @param pattern pattern that is to be tested for validity
36 * @return true if the url is valid, false otherwise38 * @return true if the url is valid, false otherwise
37 */39 */
38static bool isValidWebappUrlPattern(const QString& pattern)40bool isValidWebappUrlPattern(const QString& pattern)
39{41{
40 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.]+\\.[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$");42 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.]+\\.[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$");
41 return grammar.match(pattern).hasMatch();43 return grammar.match(pattern).hasMatch();
@@ -71,7 +73,7 @@
71 * @param pattern pattern that is to be tested for validity73 * @param pattern pattern that is to be tested for validity
72 * @return true if the url is valid, false otherwise74 * @return true if the url is valid, false otherwise
73 */75 */
74static bool isValidGoogleUrlPattern(const QString& pattern)76bool isValidGoogleUrlPattern(const QString& pattern)
75{77{
76 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\?\\*]+\\.google\\.[^\\.\\?]+/.*$");78 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\?\\*]+\\.google\\.[^\\.\\?]+/.*$");
77 return grammar.match(pattern).hasMatch();79 return grammar.match(pattern).hasMatch();
@@ -83,14 +85,31 @@
83 * @param pattern pattern that is to be tested for validity85 * @param pattern pattern that is to be tested for validity
84 * @return true if the url is valid, false otherwise86 * @return true if the url is valid, false otherwise
85 */87 */
86static bool isValidStrictUrlPattern(const QString& pattern)88bool isValidStrictUrlPattern(const QString& pattern)
87{89{
88 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$");90 static QRegularExpression grammar("^http(s|s\\?)?://[^\\.\\*\\?]+\\.[^\\.\\*\\?]+(\\.[^\\.\\*\\?/]+)*/.*$");
89 return grammar.match(pattern).hasMatch();91 return grammar.match(pattern).hasMatch();
90}92}
9193
9294
93QString UrlPatternUtils::transformWebappSearchPatternToSafePattern(const QString& pattern)95QString toSafeHostnamePartPattern(const QString& hostnamePart)
96{
97 QString localHostnamePart = hostnamePart;
98 return localHostnamePart.replace("*", "[^\\./]*");
99}
100
101QString toSafeUrlPathPartPattern(const QString& urlPathPart)
102{
103 QString localUrlPathPart = urlPathPart;
104 return localUrlPathPart.replace("*", "[^\\s]*");
105}
106
107} // namespace {
108
109
110QString UrlPatternUtils::transformWebappSearchPatternToSafePattern(
111 const QString& pattern,
112 bool doTransformUrlPath)
94{113{
95 QString transformedPattern;114 QString transformedPattern;
96115
@@ -112,8 +131,10 @@
112 // matches131 // matches
113 // https?://*.ebay.com/*132 // https?://*.ebay.com/*
114 QString scheme = match.captured(1);133 QString scheme = match.captured(1);
115 QString hostname = match.captured(2).replace("*", "[^\\./]*");134 QString hostname = toSafeHostnamePartPattern(match.captured(2));
116 QString tail = match.captured(3).replace("*", "[^\\s]*");135 QString tail = doTransformUrlPath ?
136 toSafeUrlPathPartPattern(match.captured(3))
137 : match.captured(3);
117138
118 // reconstruct139 // reconstruct
119 transformedPattern = QString("%1%2%3").arg(scheme).arg(hostname).arg(tail);140 transformedPattern = QString("%1%2%3").arg(scheme).arg(hostname).arg(tail);
@@ -128,7 +149,7 @@
128 QString scheme = match.captured(1);149 QString scheme = match.captured(1);
129 QString hostname = match.captured(2);150 QString hostname = match.captured(2);
130 QString tld = match.captured(3).replace("*", "[^\\./]*");151 QString tld = match.captured(3).replace("*", "[^\\./]*");
131 QString tail = match.captured(4).replace("*", "[^\\s]*");152 QString tail = toSafeUrlPathPartPattern(match.captured(4));
132153
133 // reconstruct154 // reconstruct
134 transformedPattern = QString("%1%2%3%4")155 transformedPattern = QString("%1%2%3%4")
135156
=== modified file 'src/app/webcontainer/url-pattern-utils.h'
--- src/app/webcontainer/url-pattern-utils.h 2014-04-01 18:45:08 +0000
+++ src/app/webcontainer/url-pattern-utils.h 2014-10-20 22:12:22 +0000
@@ -25,7 +25,8 @@
2525
26namespace UrlPatternUtils {26namespace UrlPatternUtils {
2727
28QString transformWebappSearchPatternToSafePattern(const QString&);28QString transformWebappSearchPatternToSafePattern(const QString&
29 , bool doTransformUrlPath = true);
2930
30QStringList filterAndTransformUrlPatterns(const QStringList & includePatterns);31QStringList filterAndTransformUrlPatterns(const QStringList & includePatterns);
3132
3233
=== modified file 'src/app/webcontainer/webapp-container.cpp'
--- src/app/webcontainer/webapp-container.cpp 2014-10-03 14:41:14 +0000
+++ src/app/webcontainer/webapp-container.cpp 2014-10-20 22:12:22 +0000
@@ -158,8 +158,15 @@
158158
159 context->setContextProperty("webappContainerHelper", m_webappContainerHelper.data());159 context->setContextProperty("webappContainerHelper", m_webappContainerHelper.data());
160160
161 if ( ! m_popupRedirectionUrlPrefix.isEmpty()) {161 if ( ! m_popupRedirectionUrlPrefixPattern.isEmpty()) {
162 m_window->setProperty("popupRedirectionUrlPrefix", m_popupRedirectionUrlPrefix);162 const QString WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL_ENV_VAR =
163 qgetenv("WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL");
164 m_window->setProperty(
165 "popupRedirectionUrlPrefixPattern",
166 WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL_ENV_VAR == "1"
167 ? m_popupRedirectionUrlPrefixPattern
168 : UrlPatternUtils::transformWebappSearchPatternToSafePattern(
169 m_popupRedirectionUrlPrefixPattern, false));
163 }170 }
164171
165 if (!m_userAgentOverride.isEmpty()) {172 if (!m_userAgentOverride.isEmpty()) {
@@ -172,16 +179,20 @@
172 m_window->setProperty("webviewOverrideFile", QUrl::fromLocalFile(overrideFile.absoluteFilePath()));179 m_window->setProperty("webviewOverrideFile", QUrl::fromLocalFile(overrideFile.absoluteFilePath()));
173 }180 }
174181
175 // When a webapp is being launched by name, the URL is pulled from its 'homepage'.182 const QString WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY_ENV_VAR =
176 if (m_webappName.isEmpty()) {183 qgetenv("WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY");
177 QList<QUrl> urls = this->urls();184 if (WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY_ENV_VAR == "1") {
178 if (!urls.isEmpty()) {185 m_window->setProperty("blockOpenExternalUrls", true);
179 m_window->setProperty("url", urls.last());186 }
180 } else if (m_webappModelSearchPath.isEmpty()) {187
181 return false;188 QList<QUrl> urls = this->urls();
182 }189 if (!urls.isEmpty()) {
183 // Otherwise, assume that the homepage will come from a locally defined190 m_window->setProperty("url", urls.last());
184 // webapp-properties.json file pulled from the webapp model element.191 } else if (m_webappModelSearchPath.isEmpty()) {
192 // Either we have a command line argument for the start URL or we have
193 // local search path for a webapp definition (that would include in its
194 // meta data a homepage). Any other case is faulty.
195 return false;
185 }196 }
186197
187 m_component->completeCreate();198 m_component->completeCreate();
@@ -278,7 +289,7 @@
278 } else if (argument == "--local-webapp-manifest") {289 } else if (argument == "--local-webapp-manifest") {
279 m_localWebappManifest = true;290 m_localWebappManifest = true;
280 } else if (argument.startsWith("--popup-redirection-url-prefix=")) {291 } else if (argument.startsWith("--popup-redirection-url-prefix=")) {
281 m_popupRedirectionUrlPrefix = argument.split("--popup-redirection-url-prefix=")[1];292 m_popupRedirectionUrlPrefixPattern = argument.split("--popup-redirection-url-prefix=")[1];
282 } else if (argument.startsWith("--local-cookie-db-path=")) {293 } else if (argument.startsWith("--local-cookie-db-path=")) {
283 m_localCookieStoreDbPath = argument.split("--local-cookie-db-path=")[1];294 m_localCookieStoreDbPath = argument.split("--local-cookie-db-path=")[1];
284 } else if (argument.startsWith("--user-agent-string=")) {295 } else if (argument.startsWith("--user-agent-string=")) {
285296
=== modified file 'src/app/webcontainer/webapp-container.h'
--- src/app/webcontainer/webapp-container.h 2014-09-25 20:36:59 +0000
+++ src/app/webcontainer/webapp-container.h 2014-10-20 22:12:22 +0000
@@ -56,7 +56,7 @@
56 bool m_backForwardButtonsVisible;56 bool m_backForwardButtonsVisible;
57 bool m_addressBarVisible;57 bool m_addressBarVisible;
58 bool m_localWebappManifest;58 bool m_localWebappManifest;
59 QString m_popupRedirectionUrlPrefix;59 QString m_popupRedirectionUrlPrefixPattern;
60 QString m_localCookieStoreDbPath;60 QString m_localCookieStoreDbPath;
61 QString m_userAgentOverride;61 QString m_userAgentOverride;
62 QScopedPointer<WebappContainerHelper> m_webappContainerHelper;62 QScopedPointer<WebappContainerHelper> m_webappContainerHelper;
6363
=== modified file 'src/app/webcontainer/webapp-container.qml'
--- src/app/webcontainer/webapp-container.qml 2014-10-08 09:23:14 +0000
+++ src/app/webcontainer/webapp-container.qml 2014-10-20 22:12:22 +0000
@@ -39,10 +39,11 @@
39 property var webappUrlPatterns39 property var webappUrlPatterns
40 property bool oxide: false40 property bool oxide: false
41 property string accountProvider: ""41 property string accountProvider: ""
42 property string popupRedirectionUrlPrefix: ""42 property string popupRedirectionUrlPrefixPattern: ""
43 property url webviewOverrideFile: ""43 property url webviewOverrideFile: ""
44 property var __webappCookieStore: null44 property var __webappCookieStore: null
45 property string localUserAgentOverride: ""45 property string localUserAgentOverride: ""
46 property bool blockOpenExternalUrls: false
4647
47 contentOrientation: Screen.orientation48 contentOrientation: Screen.orientation
4849
@@ -77,10 +78,10 @@
77 oxide: root.oxide78 oxide: root.oxide
78 webappModelSearchPath: root.webappModelSearchPath79 webappModelSearchPath: root.webappModelSearchPath
79 webappUrlPatterns: root.webappUrlPatterns80 webappUrlPatterns: root.webappUrlPatterns
81 blockOpenExternalUrls: root.blockOpenExternalUrls
8082
81 localUserAgentOverride: root.localUserAgentOverride83 localUserAgentOverride: root.localUserAgentOverride
8284 popupRedirectionUrlPrefixPattern: root.popupRedirectionUrlPrefixPattern
83 popupRedirectionUrlPrefix: root.popupRedirectionUrlPrefix
84 webviewOverrideFile: root.webviewOverrideFile85 webviewOverrideFile: root.webviewOverrideFile
8586
86 anchors.fill: parent87 anchors.fill: parent
@@ -107,7 +108,7 @@
107 searchPath: root.webappModelSearchPath108 searchPath: root.webappModelSearchPath
108109
109 onModelContentChanged: {110 onModelContentChanged: {
110 if (root.webappName) {111 if (root.webappName && root.url.length === 0) {
111 var idx = webappModel.getWebappIndex(root.webappName)112 var idx = webappModel.getWebappIndex(root.webappName)
112 root.url = webappModel.data(idx, UnityWebApps.UnityWebappsAppModel.Homepage)113 root.url = webappModel.data(idx, UnityWebApps.UnityWebappsAppModel.Homepage)
113 }114 }
@@ -185,8 +186,22 @@
185 browser.visible = true;186 browser.visible = true;
186 if (browser.currentWebview) {187 if (browser.currentWebview) {
187 browser.currentWebview.visible = true;188 browser.currentWebview.visible = true;
188 browser.currentWebview.url = root.url189 browser.webappName = root.webappName;
189 browser.webappName = root.webappName190
191 // As we use StateSaver to restore the URL, we need to check first if
192 // it has not been set previously before setting the URL to the default property
193 // homepage.
194 var current_url = browser.currentWebview.url.toString();
195 if (!current_url || current_url.length === 0) {
196 browser.currentWebview.url = root.url;
197 }
198 }
199 }
200
201 function updateBrowserUrl(url) {
202 root.url = url;
203 if (browser.currentWebview) {
204 browser.currentWebview.url = url;
190 }205 }
191 }206 }
192207
@@ -205,11 +220,11 @@
205 }220 }
206 var requestedUrl = uris[0].toString();221 var requestedUrl = uris[0].toString();
207222
208 if (popupRedirectionUrlPrefix.length !== 0223 if (popupRedirectionUrlPrefixPattern.length !== 0
209 && requestedUrl.indexOf(popupRedirectionUrlPrefix) === 0) {224 && requestedUrl.match(popupRedirectionUrlPrefixPattern)) {
210 return;225 return;
211 }226 }
212 browser.currentWebview.url = requestedUrl;227 updateBrowserUrl(requestedUrl);
213 }228 }
214 }229 }
215}230}
216231
=== modified file 'tests/autopilot/webapp_container/tests/__init__.py'
--- tests/autopilot/webapp_container/tests/__init__.py 2014-07-17 11:08:58 +0000
+++ tests/autopilot/webapp_container/tests/__init__.py 2014-10-20 22:12:22 +0000
@@ -20,6 +20,8 @@
2020
21from autopilot.testcase import AutopilotTestCase21from autopilot.testcase import AutopilotTestCase
22from autopilot.platform import model22from autopilot.platform import model
23from testtools.matchers import Equals
24from autopilot.matchers import Eventually
2325
24from ubuntuuitoolkit import emulators as toolkit_emulators26from ubuntuuitoolkit import emulators as toolkit_emulators
25from webapp_container.tests import fake_servers27from webapp_container.tests import fake_servers
@@ -38,16 +40,24 @@
3840
3941
40class WebappContainerTestCaseBase(AutopilotTestCase):42class WebappContainerTestCaseBase(AutopilotTestCase):
43 def setUp(self):
44 self.pointing_device = toolkit_emulators.get_pointing_device()
45 super(WebappContainerTestCaseBase, self).setUp()
46
41 def get_webcontainer_app_path(self):47 def get_webcontainer_app_path(self):
42 if os.path.exists(LOCAL_BROWSER_CONTAINER_PATH_NAME):48 if os.path.exists(LOCAL_BROWSER_CONTAINER_PATH_NAME):
43 return LOCAL_BROWSER_CONTAINER_PATH_NAME49 return LOCAL_BROWSER_CONTAINER_PATH_NAME
44 return INSTALLED_BROWSER_CONTAINER_PATH_NAME50 return INSTALLED_BROWSER_CONTAINER_PATH_NAME
4551
46 def launch_webcontainer_app(self, args):52 def launch_webcontainer_app(self, args, envvars={}):
47 if model() != 'Desktop':53 if model() != 'Desktop':
48 args.append(54 args.append(
49 '--desktop_file_hint=/usr/share/applications/'55 '--desktop_file_hint=/usr/share/applications/'
50 'webbrowser-app.desktop')56 'webbrowser-app.desktop')
57 if envvars:
58 for envvar_key in envvars:
59 self.patch_environment(envvar_key, envvars[envvar_key])
60
51 try:61 try:
52 self.app = self.launch_test_application(62 self.app = self.launch_test_application(
53 self.get_webcontainer_app_path(),63 self.get_webcontainer_app_path(),
@@ -68,15 +78,43 @@
68 def get_webcontainer_chrome(self):78 def get_webcontainer_chrome(self):
69 return self.app.select_single("Chrome")79 return self.app.select_single("Chrome")
7080
81 def get_webview(self):
82 return self.app.select_single(objectName="webview")
83
84 def get_oxide_webview(self):
85 container = self.get_webview().select_single(
86 objectName='containerWebviewLoader')
87 return container.select_single('WebViewImplOxide')
88
89 def assert_page_eventually_loaded(self, url):
90 webview = self.get_oxide_webview()
91 self.assertThat(webview.url, Eventually(Equals(url)))
92 # loadProgress == 100 ensures that a page has actually loaded
93 self.assertThat(webview.loadProgress,
94 Eventually(Equals(100), timeout=20))
95 self.assertThat(webview.loading, Eventually(Equals(False)))
96
97 def browse_to(self, url):
98 webview = self.get_oxide_webview()
99 webview.url = url
100 self.assert_page_eventually_loaded(url)
101
71102
72class WebappContainerTestCaseWithLocalContentBase(WebappContainerTestCaseBase):103class WebappContainerTestCaseWithLocalContentBase(WebappContainerTestCaseBase):
104 BASE_URL_SCHEME = 'http://'
105
73 def setUp(self):106 def setUp(self):
74 super(WebappContainerTestCaseWithLocalContentBase, self).setUp()107 super(WebappContainerTestCaseWithLocalContentBase, self).setUp()
75 self.http_server = fake_servers.WebappContainerContentHttpServer()108 self.http_server = fake_servers.WebappContainerContentHttpServer()
76 self.addCleanup(self.http_server.shutdown)109 self.addCleanup(self.http_server.shutdown)
77 self.base_url = "http://localhost:{}".format(self.http_server.port)110 self.base_url = "{}localhost:{}".format(
78111 self.BASE_URL_SCHEME, self.http_server.port)
79 def launch_webcontainer_app_with_local_http_server(self, args, path='/'):112
113 def get_base_url_hostname(self):
114 return self.base_url[len(self.BASE_URL_SCHEME):]
115
116 def launch_webcontainer_app_with_local_http_server(
117 self, args, path='/', envvars={}):
80 self.url = self.base_url + path118 self.url = self.base_url + path
81 args.append(self.url)119 args.append(self.url)
82 self.launch_webcontainer_app(args)120 self.launch_webcontainer_app(args, envvars)
83121
=== modified file 'tests/autopilot/webapp_container/tests/fake_servers.py'
--- tests/autopilot/webapp_container/tests/fake_servers.py 2014-04-24 10:50:42 +0000
+++ tests/autopilot/webapp_container/tests/fake_servers.py 2014-10-20 22:12:22 +0000
@@ -26,14 +26,28 @@
26 self.end_headers()26 self.end_headers()
27 self.wfile.write(content.encode())27 self.wfile.write(content.encode())
2828
29 def basic_html_content(self):29 def basic_html_content(self, content="basic"):
30 return """30 return """
31<html>31<html>
32<head>32<head>
33<title>Some content</title>33<title>Some content</title>
34</head>34</head>
35<body>35<body>
36This is some content36This is some {} content
37</body>
38</html>
39 """.format(content)
40
41 def redirect_html_content(self):
42 return """
43<html>
44<head>
45<title>Some content</title>
46</head>
47<body>
48<div><a href='/redirect?url=myredirect&s=1&r=2' target='_blank'>
49<div style="height: 100%; width: 100%"></div>
50</a></div>
37</body>51</body>
38</html>52</html>
39 """53 """
@@ -42,6 +56,12 @@
42 if self.path == '/':56 if self.path == '/':
43 self.send_response(200)57 self.send_response(200)
44 self.serve_content(self.basic_html_content())58 self.serve_content(self.basic_html_content())
59 elif self.path == '/other':
60 self.send_response(200)
61 self.serve_content(self.basic_html_content("other"))
62 elif self.path == '/get-redirect':
63 self.send_response(200)
64 self.serve_content(self.redirect_html_content())
45 else:65 else:
46 self.send_error(404)66 self.send_error(404)
4767
4868
=== modified file 'tests/autopilot/webapp_container/tests/test_app_launch.py'
--- tests/autopilot/webapp_container/tests/test_app_launch.py 2014-07-17 11:08:58 +0000
+++ tests/autopilot/webapp_container/tests/test_app_launch.py 2014-10-20 22:12:22 +0000
@@ -23,7 +23,7 @@
23 WebappContainerTestCaseWithLocalContentBase):23 WebappContainerTestCaseWithLocalContentBase):
2424
25 def test_container_does_not_load_with_no_webapp_name_and_url(self):25 def test_container_does_not_load_with_no_webapp_name_and_url(self):
26 args = ['--webapp']26 args = []
27 self.launch_webcontainer_app(args)27 self.launch_webcontainer_app(args)
28 self.assertIsNone(self.get_webcontainer_proxy())28 self.assertIsNone(self.get_webcontainer_proxy())
2929
3030
=== added file 'tests/autopilot/webapp_container/tests/test_redirection_pattern.py'
--- tests/autopilot/webapp_container/tests/test_redirection_pattern.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/webapp_container/tests/test_redirection_pattern.py 2014-10-20 22:12:22 +0000
@@ -0,0 +1,59 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2# Copyright 2014 Canonical
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,
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
16from testtools.matchers import Equals
17from autopilot.matchers import Eventually
18
19from webapp_container.tests import WebappContainerTestCaseWithLocalContentBase
20
21
22class WebappContainerRedirectionPatternTestCase(
23 WebappContainerTestCaseWithLocalContentBase):
24
25 def test_browse_to_redirection_pattern_url(self):
26 REDIRECTION_HOSTNAME = self.get_base_url_hostname()
27 args = ["--popup-redirection-url-prefix={}{}{}".format(
28 'http://', REDIRECTION_HOSTNAME.replace('.', '\.'),
29 '/redirect\\?url=([^&]*).*')]
30 self.launch_webcontainer_app_with_local_http_server(
31 args,
32 '/get-redirect',
33 {'WEBAPP_CONTAINER_BLOCK_OPEN_URL_EXTERNALLY': '1',
34 'WEBAPP_CONTAINER_DO_NOT_FILTER_PATTERN_URL': '1'})
35 self.get_webcontainer_window().visible.wait_for(True)
36
37 webview = self.get_oxide_webview()
38 external_open_watcher = webview.watch_signal(
39 'openExternalUrlTriggered(QString)')
40 got_redirection_url_watcher = webview.watch_signal(
41 'gotRedirectionUrl(QString)')
42
43 self.assertThat(external_open_watcher.was_emitted, Equals(False))
44 self.assertThat(got_redirection_url_watcher.was_emitted, Equals(False))
45 self.browse_to(
46 "http://{}/get-redirect".format(REDIRECTION_HOSTNAME))
47
48 self.pointing_device.click_object(webview)
49
50 self.assertThat(
51 lambda: got_redirection_url_watcher.was_emitted,
52 Eventually(Equals(True)))
53 self.assertThat(
54 webview.get_signal_emissions(
55 'gotRedirectionUrl(QString)')[0][0],
56 Equals('myredirect'))
57 self.assertThat(
58 lambda: external_open_watcher.was_emitted,
59 Eventually(Equals(True)))
060
=== modified file 'tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp'
--- tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp 2014-09-05 20:14:53 +0000
+++ tests/unittests/container-url-patterns/tst_ContainerUrlPatternsTests.cpp 2014-10-20 22:12:22 +0000
@@ -33,25 +33,32 @@
33 {33 {
34 QTest::addColumn<QString>("pattern");34 QTest::addColumn<QString>("pattern");
35 QTest::addColumn<QString>("transformedPattern");35 QTest::addColumn<QString>("transformedPattern");
36 QTest::addColumn<bool>("doTransformUrlPath");
3637
37 // regular patterns38 // regular patterns
3839
39 QTest::newRow("Valid pattern")40 QTest::newRow("Valid pattern")
40 << "https?://*.mydomain.com/*"41 << "https?://*.mydomain.com/*"
41 << "https?://[^\\./]*.mydomain.com/[^\\s]*";42 << "https?://[^\\./]*.mydomain.com/[^\\s]*"
43 << true;
44
45 QTest::newRow("Valid pattern with no tail replacement")
46 << "https?://*.mydomain.com/l.php\\?\\w+=([^&]+).*"
47 << "https?://[^\\./]*.mydomain.com/l.php\\?\\w+=([^&]+).*"
48 << false;
4249
43 QTest::newRow("Valid pattern - short url")50 QTest::newRow("Valid pattern - short url")
44 << "https?://mydomain.com/*"51 << "https?://mydomain.com/*"
45 << "https?://mydomain.com/[^\\s]*";52 << "https?://mydomain.com/[^\\s]*" << true;
4653
47 QTest::newRow("Valid pattern - strict url")54 QTest::newRow("Valid pattern - strict url")
48 << "https?://www.mydomain.com/*"55 << "https?://www.mydomain.com/*"
49 << "https?://www.mydomain.com/[^\\s]*";56 << "https?://www.mydomain.com/[^\\s]*" << true;
5057
51#define WEBAPP_INVALID_URL_PATTERN_TEST(id,invalid_url_pattern) \58#define WEBAPP_INVALID_URL_PATTERN_TEST(id,invalid_url_pattern) \
52 QTest::newRow("Invalid pattern " #id) \59 QTest::newRow("Invalid pattern " #id) \
53 << invalid_url_pattern \60 << invalid_url_pattern \
54 << QString()61 << QString() << true
5562
56 WEBAPP_INVALID_URL_PATTERN_TEST(1, "http");63 WEBAPP_INVALID_URL_PATTERN_TEST(1, "http");
57 WEBAPP_INVALID_URL_PATTERN_TEST(2, "://");64 WEBAPP_INVALID_URL_PATTERN_TEST(2, "://");
@@ -74,16 +81,16 @@
7481
75 QTest::newRow("Valid Google pattern")82 QTest::newRow("Valid Google pattern")
76 << "https?://mail.google.*/*"83 << "https?://mail.google.*/*"
77 << "https?://mail.google.[^\\./]*/[^\\s]*";84 << "https?://mail.google.[^\\./]*/[^\\s]*" << true;
7885
79 QTest::newRow("Valid non Google pattern")86 QTest::newRow("Valid non Google pattern")
80 << "https://*.google.com/*"87 << "https://*.google.com/*"
81 << "https://[^\\./]*.google.com/[^\\s]*";88 << "https://[^\\./]*.google.com/[^\\s]*" << true;
8289
83#define WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(id,invalid_google_url_pattern) \90#define WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(id,invalid_google_url_pattern) \
84 QTest::newRow("Invalid Google App pattern " #id) \91 QTest::newRow("Invalid Google App pattern " #id) \
85 << invalid_google_url_pattern \92 << invalid_google_url_pattern \
86 << QString()93 << QString() << true
8794
88 WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(1, "https://*.google.*/*");95 WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(1, "https://*.google.*/*");
89 WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(2, "https://service.gooo*gle.com/*");96 WEBAPP_INVALID_GOOGLE_URL_PATTERN_TEST(2, "https://service.gooo*gle.com/*");
@@ -99,7 +106,8 @@
99 {106 {
100 QFETCH(QString, pattern);107 QFETCH(QString, pattern);
101 QFETCH(QString, transformedPattern);108 QFETCH(QString, transformedPattern);
102 QCOMPARE(UrlPatternUtils::transformWebappSearchPatternToSafePattern(pattern), transformedPattern);109 QFETCH(bool, doTransformUrlPath);
110 QCOMPARE(UrlPatternUtils::transformWebappSearchPatternToSafePattern(pattern, doTransformUrlPath), transformedPattern);
103 }111 }
104112
105 void filteredUrlPatterns_data()113 void filteredUrlPatterns_data()

Subscribers

People subscribed via source and target branches

to status/vote changes: