diff --git a/clickable.json b/clickable.json index d6104b3d1..e0e6edde3 100644 --- a/clickable.json +++ b/clickable.json @@ -1,5 +1,5 @@ { - "template": "cmake", + "builder": "cmake", "kill": "morph-browser", "build_args": "-DCLICK_MODE=ON", "dependencies_target": [ diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index a6ac241e1..8402776ef 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -5,6 +5,7 @@ find_package(Qt5Gui REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5Qml REQUIRED) find_package(Qt5Quick REQUIRED) +find_package(Qt5Sql REQUIRED) find_package(Qt5Widgets REQUIRED) #find_package(Qt5WebEngine REQUIRED) @@ -33,6 +34,7 @@ set(COMMONLIB_SRC mime-database.cpp session-storage.cpp single-instance-manager.cpp + url-utils.cpp ) add_library(${COMMONLIB} STATIC ${COMMONLIB_SRC}) @@ -44,6 +46,7 @@ target_link_libraries(${COMMONLIB} Qt5::Network Qt5::Qml Qt5::Quick + Qt5::Sql Qt5::Widgets Qt5WebEngine Qt5WebEngineCore diff --git a/src/app/DomainPermissionsPage.qml b/src/app/DomainPermissionsPage.qml index a883a600a..0233d1d92 100644 --- a/src/app/DomainPermissionsPage.qml +++ b/src/app/DomainPermissionsPage.qml @@ -24,7 +24,6 @@ import Ubuntu.Components 1.3 import Ubuntu.Components.Popups 1.3 import Ubuntu.Content 1.3 import webbrowsercommon.private 0.1 -import "UrlUtils.js" as UrlUtils FocusScope { id: domainPermissionsItem diff --git a/src/app/DomainSettingsPage.qml b/src/app/DomainSettingsPage.qml index a19c33c9e..1506b2f28 100644 --- a/src/app/DomainSettingsPage.qml +++ b/src/app/DomainSettingsPage.qml @@ -23,7 +23,6 @@ import Ubuntu.Components 1.3 import Ubuntu.Components.Popups 1.3 import Ubuntu.Content 1.3 import webbrowsercommon.private 0.1 -import "UrlUtils.js" as UrlUtils FocusScope { id: domainSettingsItem diff --git a/src/app/DownloadsPage.qml b/src/app/DownloadsPage.qml index 20875e22c..b749bbd9a 100644 --- a/src/app/DownloadsPage.qml +++ b/src/app/DownloadsPage.qml @@ -24,7 +24,6 @@ import Ubuntu.Content 1.3 import webbrowsercommon.private 0.1 import "MimeTypeMapper.js" as MimeTypeMapper -import "UrlUtils.js" as UrlUtils import "FileUtils.js" as FileUtils BrowserPage { diff --git a/src/app/UrlUtils.js b/src/app/UrlUtils.js deleted file mode 100644 index c3d48b786..000000000 --- a/src/app/UrlUtils.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2014 Canonical Ltd. - * - * This file is part of morph-browser. - * - * morph-browser is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 3. - * - * morph-browser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ -/*jslint node: true */ -'use strict'; - -function extractScheme(url) { - var urlString = url.toString(); - return urlString.substring(0,urlString.indexOf(":")); -} - -function removeScheme(url) { - var rest = url.toString(); - var indexOfScheme = rest.indexOf(":"); - if (indexOfScheme !== -1) { - rest = rest.slice(indexOfScheme + 1); - - if (rest.indexOf("//") === 0) - { - rest = rest.slice(2); - } - } - return rest; -} - -function schemeIs(url, expectedScheme) { - return (extractScheme(url) === expectedScheme); -} - -function hasCustomScheme(url) { - - switch (extractScheme(url)) { - case 'chrome-extension': - case 'http': - case 'https': - case 'file': - case 'ftp': - case 'data': - case 'mailto': - return false; - default: - return true; - } -} - -function extractAuthority(url) { - var authority = removeScheme(url); - var indexOfPath = authority.indexOf("/"); - if (indexOfPath !== -1) { - authority = authority.slice(0, indexOfPath); - } - return authority; -} - -function extractHost(url) { - var host = extractAuthority(url); - var indexOfAt = host.indexOf("@"); - if (indexOfAt !== -1) { - host = host.slice(indexOfAt + 1); - } - var indexOfColon = host.indexOf(":"); - if (indexOfColon !== -1) { - host = host.slice(0, indexOfColon); - } - return host; -} - -function hostIs(url, expectedHost) { - return (extractHost(url) === expectedHost); -} - -function fixUrl(address) { - var url = address; - if (address.toLowerCase() === "about:blank") { - return address.toLowerCase(); - } else if (address.match(/^data:/i)) { - return "data:" + address.substr(5); - } else if (address.substr(0, 1) === "/") { - url = "file://" + address; - } else if (address.indexOf("://") === -1) { - url = "http://" + address; - } - return url; -} - -function looksLikeAUrl(address) { - if (address.match(/^data:/i)) { - return true; - } - if (address.match(/^file:/i)) { - return true; - } - if (address.match(/^view-source:/i)) { - return true; - } - if (address.match(/^chrome-extension:/i)) { - return true; - } - var terms = address.split(/\s/); - if (terms.length > 1) { - return false; - } - if (address.toLowerCase() === "about:blank") { - return true; - } - if (address.substr(0, 1) === "/") { - return true; - } - if (address.match(/^https?:\/\//i) || - address.match(/^file:\/\//i) || - address.match(/^[a-z]+:\/\//i)) { - return true; - } - if (address.split('/', 1)[0].match(/\.[a-zA-Z]{2,}$/)) { - return true; - } - if (address.split('/', 1)[0].match(/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)) { - return true; - } - return false; -} - -// special extension urls -function getPdfViewerExtensionUrlPrefix() { - return "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html?"; -} - -function isPdfViewerExtensionUrl(url) { - return (url.toString().indexOf(getPdfViewerExtensionUrlPrefix()) === 0); -} diff --git a/src/app/WebViewImpl.qml b/src/app/WebViewImpl.qml index c49a47009..5999bdef6 100644 --- a/src/app/WebViewImpl.qml +++ b/src/app/WebViewImpl.qml @@ -24,7 +24,6 @@ import QtWebEngine 1.10 import Morph.Web 0.1 import webbrowsercommon.private 0.1 import "actions" as Actions -import "UrlUtils.js" as UrlUtils WebView { id: webview diff --git a/src/app/ZoomControls.qml b/src/app/ZoomControls.qml index c666c450b..bdadbc72b 100644 --- a/src/app/ZoomControls.qml +++ b/src/app/ZoomControls.qml @@ -3,7 +3,6 @@ import Ubuntu.Components 1.3 // For UbuntuShape. import Ubuntu.Components.Popups 1.3 as Popups // For saveDialog. import QtWebEngine 1.7 import webbrowsercommon.private 0.1 // For DomainSettingsModel singleton. -import "UrlUtils.js" as UrlUtils // ZoomControls object to provide zoom menu, control and autofit logic for WebViewImpl. // Scope requirements: diff --git a/src/app/browserapplication.cpp b/src/app/browserapplication.cpp index 8085b9441..33ef81ea6 100644 --- a/src/app/browserapplication.cpp +++ b/src/app/browserapplication.cpp @@ -47,6 +47,7 @@ #include "meminfo.h" #include "mime-database.h" #include "session-storage.h" +#include "url-utils.h" BrowserApplication::BrowserApplication(int& argc, char** argv) : QApplication(argc, argv) @@ -108,6 +109,7 @@ MAKE_SINGLETON_FACTORY(DownloadsModel) MAKE_SINGLETON_FACTORY(FileOperations) MAKE_SINGLETON_FACTORY(MemInfo) MAKE_SINGLETON_FACTORY(MimeDatabase) +MAKE_SINGLETON_FACTORY(UrlUtils) MAKE_SINGLETON_FACTORY(UserAgentsModel) bool BrowserApplication::initialize(const QString& qmlFileSubPath @@ -202,6 +204,7 @@ bool BrowserApplication::initialize(const QString& qmlFileSubPath qmlRegisterSingletonType(uri, 0, 1, "MimeDatabase", MimeDatabase_singleton_factory); qmlRegisterType(uri, 0, 1, "SessionStorage"); qmlRegisterSingletonType(uri, 0, 1, "UserAgentsModel", UserAgentsModel_singleton_factory); + qmlRegisterSingletonType(uri, 0, 1, "UrlUtils", UrlUtils_singleton_factory); m_engine = new QQmlEngine; connect(m_engine, SIGNAL(quit()), SLOT(quit())); diff --git a/src/app/url-utils.cpp b/src/app/url-utils.cpp new file mode 100644 index 000000000..043b37c20 --- /dev/null +++ b/src/app/url-utils.cpp @@ -0,0 +1,126 @@ +/* + * Copyright 2019 Chris Clime + * + * This file is part of morph-browser. + * + * morph-browser is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 3. + * + * morph-browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "url-utils.h" + +namespace +{ + const QString PdfViewerChromeExtension = "mhjfbmdgcfjbbpaeojofohoefgiehjai"; +} + +UrlUtils::UrlUtils(QObject* parent) : QObject(parent) +{ +} + +QUrl UrlUtils::urlFromString(const QString& urlString) const +{ + return QUrl(urlString); +} + +QString UrlUtils::extractScheme(const QUrl& url) const +{ + return url.scheme(); +} + +QString UrlUtils::removeScheme(const QUrl& url) const +{ + QString urlWithRemovedScheme = url.adjusted(QUrl::RemoveScheme).toString(); + + return urlWithRemovedScheme.startsWith("//") ? urlWithRemovedScheme.mid(2) : urlWithRemovedScheme; +} + +bool UrlUtils::schemeIs(const QUrl& url, const QString& expected) const +{ + return (extractScheme(url) == expected); +} + +bool UrlUtils::hasCustomScheme(const QUrl& url) const +{ + QStringList knownSchemes = { "chrome-extension", "http", "https", "file", "ftp", "data", "mailto" }; + + return (! knownSchemes.contains(extractScheme(url))); +} + +QString UrlUtils::extractHost(const QUrl& url) const +{ + return url.host(); +} + +bool UrlUtils::hostIs(const QUrl& url, const QString& expected) const +{ + return (extractHost(url) == expected); +} + +QUrl UrlUtils::fixUrl(const QString& urlString) const +{ + return QUrl::fromUserInput(urlString); +} + +bool UrlUtils::looksLikeAUrl(const QString& urlString) const +{ + QUrl url = QUrl::fromUserInput(urlString); + + // containing invalid chars, e.g. spaces + if (! url.isValid()) + { + return false; + } + + // local file URL (scheme file) + if (url.isLocalFile()) + { + return true; + } + + // it can still be, that the string is rather a search string, than a URL, e.g. a single word. + if (!urlString.startsWith(url.scheme(), Qt::CaseInsensitive)) + { + // check if there are dots in the host (IPv4 address or domain) + if (url.host().contains(".")) + { + return true; + } + + // check if it is an IPv6 address + // e.g. if host() is "::1", the host part is "[::1]" + QString hostPart = url.adjusted(QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::RemovePort | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment).toString().mid(2); + + if (hostPart.startsWith("[") && hostPart.contains(":") && hostPart.endsWith("]")) + { + return true; + } + + // looks like a search (without spaces) + return false; + } + + // the url is valid (can have a custom scheme) + return true; +} + +QString UrlUtils::getPdfViewerExtensionUrlPrefix() const +{ + return QString("chrome-extension://%1/index.html?").arg(PdfViewerChromeExtension); +} + +bool UrlUtils::isPdfViewerExtensionUrl(const QUrl& url) const +{ + return url.toString().startsWith(getPdfViewerExtensionUrlPrefix()); +} + + diff --git a/src/app/url-utils.h b/src/app/url-utils.h new file mode 100644 index 000000000..9ac928d75 --- /dev/null +++ b/src/app/url-utils.h @@ -0,0 +1,78 @@ +/* + * Copyright 2019 Chris Clime + * + * This file is part of morph-browser. + * + * morph-browser is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 3. + * + * morph-browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __URL_UTILS_H__ +#define __URL_UTILS_H__ + +#include +#include + +class UrlUtils : public QObject +{ + Q_OBJECT + +public: + explicit UrlUtils(QObject* parent=0); + + Q_INVOKABLE QUrl urlFromString(const QString& urlString) const; + Q_INVOKABLE QString extractScheme(const QUrl& url) const; + Q_INVOKABLE QString removeScheme(const QUrl& url) const; + Q_INVOKABLE bool schemeIs(const QUrl& url, const QString& expected) const; + Q_INVOKABLE bool hasCustomScheme(const QUrl& url) const; + Q_INVOKABLE QString extractHost(const QUrl& url) const; + Q_INVOKABLE bool hostIs(const QUrl& url, const QString& expected) const; + Q_INVOKABLE QUrl fixUrl(const QString& urlString) const; + Q_INVOKABLE bool looksLikeAUrl(const QString& urlString) const; + + // special extension urls + Q_INVOKABLE QString getPdfViewerExtensionUrlPrefix() const; + Q_INVOKABLE bool isPdfViewerExtensionUrl(const QUrl& url) const; + + // inline functions with url provided as string from QML + Q_INVOKABLE QString inline extractScheme(const QString& urlString) const + { + return extractScheme(QUrl(urlString)); + } + Q_INVOKABLE QString inline removeScheme(const QString& urlString) const + { + return removeScheme(QUrl(urlString)); + } + Q_INVOKABLE bool inline schemeIs(const QString& urlString, const QString& expected) const + { + return schemeIs(QUrl(urlString), expected); + } + Q_INVOKABLE bool inline hasCustomScheme(const QString& urlString) const + { + return hasCustomScheme(QUrl(urlString)); + } + Q_INVOKABLE QString inline extractHost(const QString& urlString) const + { + return extractHost(QUrl(urlString)); + } + Q_INVOKABLE bool inline hostIs(const QString& urlString, const QString& expected) const + { + return hostIs(QUrl(urlString), expected); + } + + Q_INVOKABLE bool inline isPdfViewerExtensionUrl(const QString& urlString) const + { + return isPdfViewerExtensionUrl(QUrl(urlString)); + } +}; + +#endif // __URL_UTILS_H__ diff --git a/src/app/webbrowser/AddressBar.qml b/src/app/webbrowser/AddressBar.qml index 65f432322..3ddb94bb0 100644 --- a/src/app/webbrowser/AddressBar.qml +++ b/src/app/webbrowser/AddressBar.qml @@ -19,8 +19,8 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 import Ubuntu.Components.Popups 1.3 +import webbrowsercommon.private 0.1 import ".." -import "../UrlUtils.js" as UrlUtils FocusScope { id: addressbar diff --git a/src/app/webbrowser/Browser.qml b/src/app/webbrowser/Browser.qml index 39898441d..4a37a932e 100644 --- a/src/app/webbrowser/Browser.qml +++ b/src/app/webbrowser/Browser.qml @@ -30,7 +30,6 @@ import QtQuick.Controls 2.2 as QQC2 import webbrowserapp.private 0.1 import webbrowsercommon.private 0.1 import "../actions" as Actions -import "../UrlUtils.js" as UrlUtils import ".." as Common import "." as Local diff --git a/src/app/webbrowser/SettingsPage.qml b/src/app/webbrowser/SettingsPage.qml index e1f8a39e2..7004fe5e6 100644 --- a/src/app/webbrowser/SettingsPage.qml +++ b/src/app/webbrowser/SettingsPage.qml @@ -24,8 +24,8 @@ import Ubuntu.Components.Popups 1.3 import QtWebEngine 1.5 import Morph.Web 0.1 import webbrowserapp.private 0.1 +import webbrowsercommon.private 0.1 import ".." as Common -import "../UrlUtils.js" as UrlUtils FocusScope { id: settingsItem diff --git a/src/app/webbrowser/TabComponent.qml b/src/app/webbrowser/TabComponent.qml index bdb764f83..5318b7dd6 100644 --- a/src/app/webbrowser/TabComponent.qml +++ b/src/app/webbrowser/TabComponent.qml @@ -20,9 +20,9 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 import Ubuntu.Components.Popups 1.3 import webbrowserapp.private 0.1 +import webbrowsercommon.private 0.1 import QtWebEngine 1.5 import "../actions" as Actions -import "../UrlUtils.js" as UrlUtils import ".." // FIXME: This component breaks encapsulation: it uses variables not defined in diff --git a/src/app/webcontainer/WebViewImplOxide.qml b/src/app/webcontainer/WebViewImplOxide.qml index ba96ef33e..e9dc7dfd6 100644 --- a/src/app/webcontainer/WebViewImplOxide.qml +++ b/src/app/webcontainer/WebViewImplOxide.qml @@ -23,7 +23,6 @@ import Ubuntu.Components.Popups 1.3 import QtWebEngine 1.7 import Morph.Web 0.1 import webbrowsercommon.private 0.1 -import "../UrlUtils.js" as UrlUtils import ".." WebappWebview { diff --git a/src/app/webcontainer/WebappContainerWebview.qml b/src/app/webcontainer/WebappContainerWebview.qml index 0776deab0..a0c3fa681 100644 --- a/src/app/webcontainer/WebappContainerWebview.qml +++ b/src/app/webcontainer/WebappContainerWebview.qml @@ -20,8 +20,8 @@ import QtQuick 2.4 import QtQuick.Window 2.2 import Ubuntu.Components 1.3 import Ubuntu.Unity.Action 1.1 as UnityActions +import webbrowsercommon.private 0.1 import "../actions" as Actions -import "../UrlUtils.js" as UrlUtils import ".." FocusScope { diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt index 5a637bb45..5d65fc276 100644 --- a/tests/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -24,4 +24,4 @@ add_subdirectory(downloads-model) add_subdirectory(single-instance-manager) add_subdirectory(meminfo) add_subdirectory(webapp-container-color-helper) - +add_subdirectory(url-utils) diff --git a/tests/unittests/qml/CMakeLists.txt b/tests/unittests/qml/CMakeLists.txt index 2613a0829..d70582b7a 100644 --- a/tests/unittests/qml/CMakeLists.txt +++ b/tests/unittests/qml/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES ${morph-browser_SOURCE_DIR}/bookmarks-folder-model.cpp ${morph-browser_SOURCE_DIR}/bookmarks-folderlist-model.cpp ${webbrowser-common_SOURCE_DIR}/file-operations.cpp + ${webbrowser-common_SOURCE_DIR}/url-utils.cpp ${morph-browser_SOURCE_DIR}/history-domain-model.cpp ${morph-browser_SOURCE_DIR}/history-domainlist-model.cpp ${morph-browser_SOURCE_DIR}/history-model.cpp diff --git a/tests/unittests/qml/tst_AddressBar.qml b/tests/unittests/qml/tst_AddressBar.qml index 00881c353..09045100d 100644 --- a/tests/unittests/qml/tst_AddressBar.qml +++ b/tests/unittests/qml/tst_AddressBar.qml @@ -90,11 +90,11 @@ Item { return [ {url: "file:///usr/share/doc/ubuntu-online-tour/index.html"}, {url: "http://ubuntu.com"}, - {url: "https://google.com"}, + {url: "https://ubports.com"}, {url: "ftp://ubuntu.com"}, {url: "about:blank"}, {url: "data:,A brief note"}, - {url: "http://com.google"} + {url: "http://com.ubports"} ] } @@ -198,9 +198,9 @@ Item { {text: "HTTPS://www.ubuntu.com", requestedUrl: "https://www.ubuntu.com"}, {text: "FILE:///usr/share/doc/ubuntu-online-tour/index.html", requestedUrl: "file:///usr/share/doc/ubuntu-online-tour/index.html"}, {text: "FTP://ubuntu.com", requestedUrl: "ftp://ubuntu.com"}, - {text: "ABOUT:BLANK", requestedUrl: "about:blank"}, + {text: "ABOUT:BLANK", requestedUrl: "about:BLANK"}, {text: "DATA:,A brief note", requestedUrl: "data:,A brief note"}, - {text: "HTTP://com.GOOGLE", requestedUrl: "http://com.google"} + {text: "HTTP://com.UBPORTS", requestedUrl: "http://com.ubports"} ] } @@ -250,9 +250,9 @@ Item { {input: "en.wikipedia.org/wiki/Foo", simplified: "en.wikipedia.org", actualUrl: "http://en.wikipedia.org/wiki/Foo"}, - {input: "http://com.google", - simplified: "com.google", - actualUrl: "http://com.google"}, + {input: "http://com.ubports", + simplified: "com.ubports", + actualUrl: "http://com.ubports"}, ] } diff --git a/tests/unittests/qml/tst_QmlTests.cpp b/tests/unittests/qml/tst_QmlTests.cpp index 4945ae85f..ce367bb14 100644 --- a/tests/unittests/qml/tst_QmlTests.cpp +++ b/tests/unittests/qml/tst_QmlTests.cpp @@ -39,6 +39,7 @@ #include "searchengine.h" #include "tabs-model.h" #include "text-search-filter-model.h" +#include "url-utils.h" class TestContext : public QObject { @@ -167,12 +168,14 @@ MAKE_SINGLETON_FACTORY(BookmarksModel) MAKE_SINGLETON_FACTORY(HistoryModelMock) MAKE_SINGLETON_FACTORY(TestContext) MAKE_SINGLETON_FACTORY(Reparenter) +MAKE_SINGLETON_FACTORY(UrlUtils) int main(int argc, char** argv) { const char* commonUri = "webbrowsercommon.private"; qmlRegisterType(commonUri, 0, 1, "FaviconFetcher"); qmlRegisterSingletonType(commonUri, 0, 1, "FileOperations", FileOperations_singleton_factory); + qmlRegisterSingletonType(commonUri, 0, 1, "UrlUtils", UrlUtils_singleton_factory); const char* browserUri = "webbrowserapp.private"; qmlRegisterType(browserUri, 0, 1, "SearchEngine"); diff --git a/tests/unittests/qml/tst_UrlUtils.qml b/tests/unittests/qml/tst_UrlUtils.qml deleted file mode 100644 index 9569833cd..000000000 --- a/tests/unittests/qml/tst_UrlUtils.qml +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2014 Canonical Ltd. - * - * This file is part of webbrowser-app. - * - * webbrowser-app is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 3. - * - * webbrowser-app is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import QtTest 1.0 -import "../../../src/app/UrlUtils.js" as UrlUtils - -TestCase { - name: "UrlUtils" - - function test_extractAuthority_data() { - return [ - {url: "", authority: ""}, - {url: "http://example.org/", authority: "example.org"}, - {url: "http://www.example.org/", authority: "www.example.org"}, - {url: "http://www.example.org/foo/bar", authority: "www.example.org"}, - {url: "http://example.org:2442/foo", authority: "example.org:2442"}, - {url: "http://user:pwd@example.org/", authority: "user:pwd@example.org"}, - {url: "http://user:pwd@example.org:2442/", authority: "user:pwd@example.org:2442"}, - {url: "ftp://user:pwd@example.org:21/foo/bar", authority: "user:pwd@example.org:21"} - ] - } - - function test_extractAuthority(data) { - compare(UrlUtils.extractAuthority(data.url), data.authority) - } - - function test_extractHost_data() { - return [ - {url: "http://example.org/", host: "example.org"}, - {url: "http://www.example.org/", host: "www.example.org"}, - {url: "http://www.example.org/foo/bar", host: "www.example.org"}, - {url: "http://example.org:2442/foo", host: "example.org"}, - {url: "http://user:pwd@example.org/", host: "example.org"}, - {url: "http://user:pwd@example.org:2442/", host: "example.org"}, - {url: "ftp://user:pwd@example.org:21/foo/bar", host: "example.org"} - ] - } - - function test_extractHost(data) { - compare(UrlUtils.extractHost(data.url), data.host) - } - - function test_removeScheme_data() { - return [ - {url: "http://example.org/", removed: "example.org/"}, - {url: "file://user:pwd@example.org:2442/", removed: "user:pwd@example.org:2442/"}, - {url: "file:///home/foo/bar.txt", removed: "/home/foo/bar.txt"}, - {url: "ht+tp://www.example.org/", removed: "www.example.org/"}, - {url: "www.example.org", removed: "www.example.org"}, - ] - } - - function test_removeScheme(data) { - compare(UrlUtils.removeScheme(data.url), data.removed) - } - - function test_looksLikeAUrl_data() { - return [ - {url: "", looksLike: false}, - {url: "http://example.org/", looksLike: true}, - {url: "example.org", looksLike: true}, - {url: "http://www.example.org?q=foo bar", looksLike: false}, - {url: "about:blank", looksLike: true}, - {url: "file:///usr/foo/bar", looksLike: true}, - {url: "hello://my/name/is/", looksLike: true}, - {url: "192.168.1.0", looksLike: true} - ] - } - - function test_looksLikeAUrl(data) { - compare(UrlUtils.looksLikeAUrl(data.url), data.looksLike) - } - - function test_fixUrl_data() { - return [ - {url: "About:BLANK", fixed: "about:blank"}, - {url: "/usr/bin/", fixed: "file:///usr/bin/"}, - {url: "example.org", fixed: "http://example.org"} - ] - } - - function test_fixUrl(data) { - compare(UrlUtils.fixUrl(data.url), data.fixed) - } -} diff --git a/tests/unittests/url-utils/CMakeLists.txt b/tests/unittests/url-utils/CMakeLists.txt new file mode 100644 index 000000000..a1a0447c7 --- /dev/null +++ b/tests/unittests/url-utils/CMakeLists.txt @@ -0,0 +1,14 @@ +find_package(Qt5Core REQUIRED) +find_package(Qt5Sql REQUIRED) +find_package(Qt5Test REQUIRED) +set(TEST tst_UrlUtilsTests) +add_executable(${TEST} tst_UrlUtilsTests.cpp) +include_directories(${morph-browser_SOURCE_DIR} ${webbrowser-common_SOURCE_DIR}) +target_link_libraries(${TEST} + Qt5::Core + Qt5::Sql + Qt5::Test + webbrowser-common +) +add_test(${TEST} ${CMAKE_CURRENT_BINARY_DIR}/${TEST}) +set_tests_properties(${TEST} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal") diff --git a/tests/unittests/url-utils/tst_UrlUtilsTests.cpp b/tests/unittests/url-utils/tst_UrlUtilsTests.cpp new file mode 100644 index 000000000..b9937a4a5 --- /dev/null +++ b/tests/unittests/url-utils/tst_UrlUtilsTests.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This file is part of webbrowser-app. + * + * webbrowser-app is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 3. + * + * webbrowser-app is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Qt +#include + +// local +#include "url-utils.h" + +class UrlUtilsTests : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void test_extractHost_data() + { + QTest::addColumn("url"); + QTest::addColumn("host"); + QTest::newRow("row1") << QUrl("http://example.org/") << QString("example.org"); + QTest::newRow("row2") << QUrl("http://www.example.org/") << QString("www.example.org"); + QTest::newRow("row3") << QUrl("http://www.example.org/foo/bar") << QString("www.example.org"); + QTest::newRow("row4") << QUrl("http://example.org:2442/foo") << QString("example.org"); + QTest::newRow("row5") << QUrl("http://user:pwd@example.org/") << QString("example.org"); + QTest::newRow("row6") << QUrl("http://user:pwd@example.org:2442/") << QString("example.org"); + QTest::newRow("row7") << QUrl("ftp://user:pwd@example.org:21/foo/bar") << QString("example.org"); + } + + void test_extractHost() + { + QFETCH(QUrl, url); + QFETCH(QString, host); + UrlUtils urlUtils; + QCOMPARE(urlUtils.extractHost(url), host); + } + + void test_extractScheme_data() + { + QTest::addColumn("url"); + QTest::addColumn("scheme"); + QTest::newRow("row1") << QUrl("http://example.org/") << QString("http"); + QTest::newRow("row2") << QUrl("file://user:pwd@example.org:2442/") << QString("file"); + QTest::newRow("row3") << QUrl("file:///home/foo/bar.txt") << QString("file"); + QTest::newRow("row4") << QUrl("appid://com.ubuntu.terminal/terminal/current-user-version") << QString("appid"); + QTest::newRow("row5") << QUrl("www.example.org") << QString(""); + } + + void test_extractScheme() + { + QFETCH(QUrl, url); + QFETCH(QString, scheme); + UrlUtils urlUtils; + QCOMPARE(urlUtils.extractScheme(url), scheme); + } + + void test_removeScheme_data() + { + QTest::addColumn("url"); + QTest::addColumn("removed"); + QTest::newRow("row1") << QUrl("http://example.org/") << QString("example.org/"); + QTest::newRow("row2") << QUrl("file://user:pwd@example.org:2442/") << QString("user:pwd@example.org:2442/"); + QTest::newRow("row3") << QUrl("file:///home/foo/bar.txt") << QString("/home/foo/bar.txt"); + QTest::newRow("row4") << QUrl("appid://com.ubuntu.terminal/terminal/current-user-version") << QString("com.ubuntu.terminal/terminal/current-user-version"); + QTest::newRow("row5") << QUrl("www.example.org") << QString("www.example.org"); + } + + void test_removeScheme() + { + QFETCH(QUrl, url); + QFETCH(QString, removed); + UrlUtils urlUtils; + QCOMPARE(urlUtils.removeScheme(url), removed); + } + + void test_looksLikeAUrl_data() + { + QTest::addColumn("urlString"); + QTest::addColumn("looksLike"); + QTest::newRow("row1") << QString("") << false; + QTest::newRow("row2") << QString("http://example.org/") << true; + QTest::newRow("row3") << QString("example.org") << true; + QTest::newRow("row4") << QString("http://www.example.org?q=foo bar") << true; + QTest::newRow("row5") << QString("about:blank") << true; + QTest::newRow("row6") << QString("file:///usr/foo/bar") << true; + QTest::newRow("row7") << QString("hello://my/name/is/") << true; + QTest::newRow("row8") << QString("192.168.1.0") << true; + QTest::newRow("row9") << QString("foo") << false; + QTest::newRow("row10") << QString("foo bar") << false; + QTest::newRow("row11") << QString("www.example.org search") << false; + } + + void test_looksLikeAUrl() + { + QFETCH(QString, urlString); + QFETCH(bool, looksLike); + UrlUtils urlUtils; + QCOMPARE(urlUtils.looksLikeAUrl(urlString), looksLike); + } + + void test_fixUrl_data() + { + QTest::addColumn("urlString"); + QTest::addColumn("fixedUrl"); + QTest::newRow("row1") << QString("About:BLANK") << QUrl("about:BLANK"); + QTest::newRow("row2") << QString("/usr/bin/") << QUrl("file:///usr/bin/"); + QTest::newRow("row3") << QString("example.org") << QUrl("http://example.org"); + } + + void test_fixUrl() + { + QFETCH(QString, urlString); + QFETCH(QUrl, fixedUrl); + UrlUtils urlUtils; + QCOMPARE(urlUtils.fixUrl(urlString), fixedUrl); + } + +}; + +QTEST_MAIN(UrlUtilsTests) +#include "tst_UrlUtilsTests.moc"