diff options
author | Liang Qi <liang.qi@qt.io> | 2016-09-24 06:43:50 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-09-24 06:43:50 +0200 |
commit | e2371f2be8e98ffc124286a3bf5a17dc55c97ec1 (patch) | |
tree | 59814e9aea5246783487c57fd84d8c0974e9b7de | |
parent | 75855e9bfbaad72a2b8c3ff3107661abce9e67a8 (diff) | |
parent | ab389a568e0c088d4e5ced024ec2782439d8b2fe (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Change-Id: I285130d29b64c2cbaafa5302fa16d5ba75bc3ade
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | .tag | 1 | ||||
-rw-r--r-- | src/oauth/doc/qtnetworkauth.qdocconf | 40 | ||||
-rw-r--r-- | src/oauth/doc/src/qtnetworkauth.qdoc | 75 | ||||
-rw-r--r-- | src/oauth/oauth.pro | 2 | ||||
-rw-r--r-- | src/oauth/qabstractoauth.cpp | 201 | ||||
-rw-r--r-- | src/oauth/qabstractoauth_p.h | 2 | ||||
-rw-r--r-- | src/oauth/qoauth1.cpp | 29 | ||||
-rw-r--r-- | src/oauth/qoauth1.h | 2 | ||||
-rw-r--r-- | src/oauth/qoauth1_p.h | 5 | ||||
-rw-r--r-- | tests/auto/abstractoauth/abstractoauth.pro | 6 | ||||
-rw-r--r-- | tests/auto/abstractoauth/tst_abstractoauth.cpp | 79 | ||||
-rw-r--r-- | tests/auto/auto.pro | 4 | ||||
-rw-r--r-- | tests/auto/oauth1/tst_oauth1.cpp | 148 |
14 files changed, 579 insertions, 17 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0909f7a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.tag export-subst +.gitattributes export-ignore @@ -0,0 +1 @@ +$Format:%H$ diff --git a/src/oauth/doc/qtnetworkauth.qdocconf b/src/oauth/doc/qtnetworkauth.qdocconf new file mode 100644 index 0000000..05cc336 --- /dev/null +++ b/src/oauth/doc/qtnetworkauth.qdocconf @@ -0,0 +1,40 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtNetworkAuth +description = Qt Network Authorization Reference Documentation +version = $QT_VERSION + +qhp.projects = QtNetworkAuth + +qhp.QtNetworkAuth.file = qtnetworkauth.qhp +qhp.QtNetworkAuth.namespace = org.qt-project.qtnetworkauth.$QT_VERSION_TAG +qhp.QtNetworkAuth.virtualFolder = qtnetworkauth +qhp.QtNetworkAuth.indexTitle = Qt Network Authorization +qhp.QtNetworkAuth.indexRoot = + +qhp.QtNetworkAuth.filterAttributes = qtnetworkauth $QT_VERSION qtrefdoc +qhp.QtNetworkAuth.customFilters.Qt.name = QtNetworkAuthorization $QT_VERSION +qhp.QtNetworkAuth.customFilters.Qt.filterAttributes = qtnetworkauth $QT_VERSION + +qhp.QtNetworkAuth.subprojects = classes +qhp.QtNetworkAuth.subprojects.classes.title = C++ Classes +qhp.QtNetworkAuth.subprojects.classes.indexTitle = Qt Network Authorization C++ Classes +qhp.QtNetworkAuth.subprojects.classes.selectors = class doc:headerfile +qhp.QtNetworkAuth.subprojects.classes.sortPages = true + +tagfile = qtnetworkauth.tags + +depends += qtcore qtnetwork qtdoc + +headerdirs += .. +sourcedirs += .. +#imagedirs += images + +#examplesinstallpath = oauth +#exampledirs += ../../../examples/oauth + +navigation.landingpage = "Qt Network Authorization" +navigation.cppclassespage = "Qt Network Authorization C++ Classes" + +# TODO: Remove once out of technology preview +navigation.homepage = "Qt Documentation (Technology Preview)" diff --git a/src/oauth/doc/src/qtnetworkauth.qdoc b/src/oauth/doc/src/qtnetworkauth.qdoc new file mode 100644 index 0000000..7386670 --- /dev/null +++ b/src/oauth/doc/src/qtnetworkauth.qdoc @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtnetworkauth-index.html + \title Qt Network Authorization + \brief Provides network authorization capabilities (OAuth). + + Qt Network Authorization provides a set of APIs that enable Qt + applications to obtain limited access to online accounts and + HTTP services without exposing users' passwords. + + Currently, the supported authorization protocol is \l {https://oauth.net} + {OAuth}, versions 1 and 2. + + \section1 Getting Started + +//! [qtnetworkauth-usage] + To use Qt Network Authorization classes, add this directive into C++ files: + + \code + #include <QtNetworkAuth> + \endcode + + To link against the Qt Network Authorization module, add this line to the + project file: + + \code + QT += network networkauth + \endcode +//! [qtnetworkauth-usage] + + \omit + \section1 Overview + TODO + \endomit + + \section1 API Reference + \list + \li \l{Qt Network Authorization C++ Classes}{C++ Classes} + \endlist +*/ +/*! + \module QtNetworkAuth + \title Qt Network Authorization C++ Classes + \ingroup modules + \qtvariable networkauth + \brief Provides classes for network authorization support (OAuth). + + \include qtnetworkauth.qdoc qtnetworkauth-usage +*/ diff --git a/src/oauth/oauth.pro b/src/oauth/oauth.pro index 3060605..19af5c2 100644 --- a/src/oauth/oauth.pro +++ b/src/oauth/oauth.pro @@ -34,4 +34,6 @@ SOURCES += \ HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS +QMAKE_DOCS = $$PWD/doc/qtnetworkauth.qdocconf + load(qt_module) diff --git a/src/oauth/qabstractoauth.cpp b/src/oauth/qabstractoauth.cpp index 4d9e259..0f34fa2 100644 --- a/src/oauth/qabstractoauth.cpp +++ b/src/oauth/qabstractoauth.cpp @@ -60,13 +60,125 @@ Q_DECLARE_METATYPE(QAbstractOAuth::Error) QT_BEGIN_NAMESPACE +/*! + \class QAbstractOAuth + \inmodule QtNetworkAuth + \ingroup oauth + \brief The QAbstractOAuth class is the base of all + implementations of OAuth authentication methods. + \since 5.8 + + The class defines the basic interface of the OAuth + authentication classes. By inheriting this class, you + can create custom authentication methods for different web + services. + + It also contains some functions to ease the process of + implementing different authentication flows. +*/ + +/*! + \enum QAbstractOAuth::Status + + Indicates the current authentication status. + + \value NotAuthenticated No token has been + retrieved. + + \value TemporaryCredentialsReceived Temporary credentials + have been received, this status is used in some OAuth + authetication methods. + + \value Granted Token credentials have + been received and authenticated calls are allowed. + + \value RefreshingToken New token credentials + have been requested. +*/ + +/*! + \enum QAbstractOAuth::Stage + + Identifies an authentication stage. It's passed to a + ModifyParametersFunction so that it can make different changes to + parameters at each call to it during the process of + authentication. + + \value RequestingTemporaryCredentials Preparing the temporary + credentials request. + + \value RequestingAuthorization Preparing the + authorization grant URL. + + \value RequestingAccessToken Preparing the token + request. +*/ + +/*! + \enum QAbstractOAuth::Error + + Indicates the latest received error. + + \value NoError No error has ocurred. + + \value NetworkError Failed to connect to the server. + + \value ServerError The server answered the + request with an error. + + \value OAuthTokenNotFoundError The server's response to + a token request provided no token identifier. + + \value OAuthTokenSecretNotFoundError The server's response to + a token request provided no token secret. + + \value OAuthCallbackNotVerified The authorization server + has not verified the supplied callback URI in the request. This + usually happens when the provided callback does not match with + the callback supplied during client registration. +*/ + +/*! + \property QAbstractOAuth::status + \brief This property holds the current authentication status. +*/ + +/*! + \property QAbstractOAuth::extraTokens + \brief This property holds the extra tokens received from the + server. +*/ + +/*! + \property QAbstractOAuth::authorizationUrl + \brief This property holds the URL used to request the Resource + Owner Authorization. + + \b {See also} \l {https://tools.ietf.org/html/rfc5849#section-2.2} + {The OAuth 1.0 Protocol: Resource Owner Authorization}. +*/ + +/*! + \fn void QAbstractOAuth::authorizeWithBrowser(const QUrl &url) + This signal is emitted when the URL \a url, generated by + resourceOwnerAuthorization(), is ready to be used in the web + browser to allow the application to impersonate the user. +*/ + +/*! + \fn void QAbstractOAuth::granted() + This signal is emitted when the authorization flow finishes + successfully. +*/ + QAbstractOAuthPrivate::QAbstractOAuthPrivate(QNetworkAccessManager *manager) : QAbstractOAuthPrivate(QUrl(), manager) {} QAbstractOAuthPrivate::QAbstractOAuthPrivate(const QUrl &authorizationUrl, QNetworkAccessManager *manager) : - authorizationUrl(authorizationUrl), defaultReplyHandler(new QOAuthOobReplyHandler), + authorizationUrl(authorizationUrl), + defaultReplyHandler(new QOAuthOobReplyHandler), networkAccessManagerPointer(manager) {} @@ -118,15 +230,36 @@ QAbstractOAuth::QAbstractOAuth(QAbstractOAuthPrivate &dd, QObject *parent) qRegisterMetaType<QAbstractOAuth::Error>(); } +/*! + Destroys the abstract OAuth. +*/ QAbstractOAuth::~QAbstractOAuth() {} +/*! + Returns the current network access manager used to send the + requests to the server during authentication flows or to make + authentication calls. + + \sa setNetworkAccessManager(), QNetworkAccessManager +*/ QNetworkAccessManager *QAbstractOAuth::networkAccessManager() const { Q_D(const QAbstractOAuth); return d->networkAccessManagerPointer.data(); } +/*! + Sets the network manager to \a networkAccessManager. + QAbstractOAuth does not take ownership of + \a networkAccessManager. If no custom network access manager is + set, an internal network access manager is used. + This network access manager will be used + to make the request to the authentication server and the + authenticated request to the web service. + + \sa networkAccessManager(), QNetworkAccessManager +*/ void QAbstractOAuth::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager) { Q_D(QAbstractOAuth); @@ -137,18 +270,32 @@ void QAbstractOAuth::setNetworkAccessManager(QNetworkAccessManager *networkAcces } } +/*! + Returns the current authentication status. + \sa Status +*/ QAbstractOAuth::Status QAbstractOAuth::status() const { Q_D(const QAbstractOAuth); return d->status; } +/*! + Returns the authorization request URL. + \sa setAuthorizationUrl() +*/ QUrl QAbstractOAuth::authorizationUrl() const { Q_D(const QAbstractOAuth); return d->authorizationUrl; } +/*! + Sets the authorization request URL to \a url. This address + will be used to allow the user to grant the application the + ability to make authenticated calls on behalf of the user. + \sa authorizationUrl() +*/ void QAbstractOAuth::setAuthorizationUrl(const QUrl &url) { Q_D(QAbstractOAuth); @@ -158,6 +305,11 @@ void QAbstractOAuth::setAuthorizationUrl(const QUrl &url) } } +/*! + Sets the current status to \a status. This method is for use + by classes based on QAbstractOAuth. + \sa status() +*/ void QAbstractOAuth::setStatus(QAbstractOAuth::Status status) { Q_D(QAbstractOAuth); @@ -167,24 +319,43 @@ void QAbstractOAuth::setStatus(QAbstractOAuth::Status status) } } +/*! + Returns the reply handler currently in use. + \sa setReplyHandler(), QAbstractOAuthReplyHandler +*/ QAbstractOAuthReplyHandler *QAbstractOAuth::replyHandler() const { Q_D(const QAbstractOAuth); return d->replyHandler ? d->replyHandler.data() : d->defaultReplyHandler.data(); } +/*! + Sets the current reply handler to \a handler. + \note Does not take ownership of \a handler. +*/ void QAbstractOAuth::setReplyHandler(QAbstractOAuthReplyHandler *handler) { Q_D(QAbstractOAuth); d->replyHandler = handler; } +/*! + Returns the current parameter-modification function. + \sa ModifyParametersFunction, setModifyParametersFunction(), Stage +*/ QAbstractOAuth::ModifyParametersFunction QAbstractOAuth::modifyParametersFunction() const { Q_D(const QAbstractOAuth); return d->modifyParametersFunction; } +/*! + Sets the parameter-modification function. This function is used + to customize the parameters sent to the server during a specified + authorization stage. The number of calls to this function + depends on the flow used during the authentication. + \sa modifyParametersFunction(), ModifyParametersFunction, Stage +*/ void QAbstractOAuth::setModifyParametersFunction( const QAbstractOAuth::ModifyParametersFunction &modifyParametersFunction) { @@ -192,12 +363,24 @@ void QAbstractOAuth::setModifyParametersFunction( d->modifyParametersFunction = modifyParametersFunction; } +/*! + Returns the extra tokens received from the server during + authentication. + \sa extraTokensChanged() +*/ QVariantMap QAbstractOAuth::extraTokens() const { Q_D(const QAbstractOAuth); return d->extraTokens; } +/*! + Returns the current callback string corresponding to the + current reply handler. The returned string is the string + sent to the server to specify the callback URI, or the word + identifying the alternative method in headless devices. + \sa replyHandler(), setReplyHandler() +*/ QString QAbstractOAuth::callback() const { Q_D(const QAbstractOAuth); @@ -205,6 +388,14 @@ QString QAbstractOAuth::callback() const : d->defaultReplyHandler->callback(); } +/*! + Builds the resource owner authorization URL to be used in the web + browser: \a url is used as the base URL and the query is created + using \a parameters. When the URL is ready, the + authorizeWithBrowser() signal will be emitted with the generated + URL. + \sa authorizeWithBrowser() +*/ void QAbstractOAuth::resourceOwnerAuthorization(const QUrl &url, const QVariantMap ¶meters) { QUrl u = url; @@ -212,6 +403,14 @@ void QAbstractOAuth::resourceOwnerAuthorization(const QUrl &url, const QVariantM Q_EMIT authorizeWithBrowser(u); } +/*! + Generates a random string which could be used as state or nonce. + The parameter \a length determines the size of the generated + string. + + \b {See also} \l {https://tools.ietf.org/html/rfc5849#section-3.3}{The + OAuth 1.0 Protocol: Nonce and Timestamp}. +*/ QByteArray QAbstractOAuth::generateRandomString(quint8 length) { return QAbstractOAuthPrivate::generateRandomString(length); diff --git a/src/oauth/qabstractoauth_p.h b/src/oauth/qabstractoauth_p.h index 214108c..ca41ef9 100644 --- a/src/oauth/qabstractoauth_p.h +++ b/src/oauth/qabstractoauth_p.h @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE class QUrlQuery; -class QAbstractOAuthPrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QAbstractOAuthPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QAbstractOAuth) diff --git a/src/oauth/qoauth1.cpp b/src/oauth/qoauth1.cpp index 3ccb238..4251c3e 100644 --- a/src/oauth/qoauth1.cpp +++ b/src/oauth/qoauth1.cpp @@ -72,8 +72,10 @@ const QString Key::oauthTokenSecret = QStringLiteral("oauth_token_secret" const QString Key::oauthVerifier = QStringLiteral("oauth_verifier"); const QString Key::oauthVersion = QStringLiteral("oauth_version"); -QOAuth1Private::QOAuth1Private(QNetworkAccessManager *networkAccessManager) - : QAbstractOAuthPrivate(networkAccessManager) +QOAuth1Private::QOAuth1Private(const QPair<QString, QString> &clientCredentials, + QNetworkAccessManager *networkAccessManager) : + QAbstractOAuthPrivate(networkAccessManager), + clientCredentials(clientCredentials) { qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); } @@ -236,27 +238,28 @@ void QOAuth1Private::_q_tokensReceived(const QVariantMap &tokens) case QAbstractOAuth::Status::RefreshingToken: break; } - } -QOAuth1::QOAuth1(QObject *parent) - : QAbstractOAuth(*new QOAuth1Private, parent) +QOAuth1::QOAuth1(QObject *parent) : + QOAuth1(nullptr, + parent) {} -QOAuth1::QOAuth1(QNetworkAccessManager *manager, QObject *parent) - : QAbstractOAuth(*new QOAuth1Private(manager), parent) +QOAuth1::QOAuth1(QNetworkAccessManager *manager, QObject *parent) : + QOAuth1(QString(), + QString(), + manager, + parent) {} QOAuth1::QOAuth1(const QString &clientIdentifier, const QString &clientSharedSecret, QNetworkAccessManager *manager, QObject *parent) - : QAbstractOAuth(*new QOAuth1Private(manager), parent) -{ - Q_D(QOAuth1); - d->clientCredentials.first = clientIdentifier; - d->clientCredentials.second = clientSharedSecret; -} + : QAbstractOAuth(*new QOAuth1Private(qMakePair(clientIdentifier, clientSharedSecret), + manager), + parent) +{} QOAuth1::~QOAuth1() {} diff --git a/src/oauth/qoauth1.h b/src/oauth/qoauth1.h index 3d13645..d102552 100644 --- a/src/oauth/qoauth1.h +++ b/src/oauth/qoauth1.h @@ -117,7 +117,7 @@ public Q_SLOTS: void continueGrantWithVerifier(const QString &verifier); Q_SIGNALS: - void signatureMethodChanged(SignatureMethod method); + void signatureMethodChanged(QOAuth1::SignatureMethod method); void clientSharedSecretChanged(const QString &credential); void tokenSecretChanged(const QString &token); void temporaryCredentialsUrlChanged(const QUrl &url); diff --git a/src/oauth/qoauth1_p.h b/src/oauth/qoauth1_p.h index 167aed2..e1bed46 100644 --- a/src/oauth/qoauth1_p.h +++ b/src/oauth/qoauth1_p.h @@ -59,7 +59,9 @@ #include <QtNetworkAuth/qoauthglobal.h> #include <QtCore/qurl.h> +#include <QtCore/qpair.h> #include <QtCore/qobject.h> +#include <QtCore/qstring.h> #include <QtNetwork/qnetworkreply.h> #include <QtNetwork/qnetworkaccessmanager.h> @@ -71,7 +73,8 @@ class QOAuth1Private : public QAbstractOAuthPrivate Q_DECLARE_PUBLIC(QOAuth1) public: - QOAuth1Private(QNetworkAccessManager *networkAccessManager = nullptr); + QOAuth1Private(const QPair<QString, QString> &clientCredentials, + QNetworkAccessManager *networkAccessManager = nullptr); void appendCommonHeaders(QVariantMap *headers); void appendSignature(QAbstractOAuth::Stage stage, diff --git a/tests/auto/abstractoauth/abstractoauth.pro b/tests/auto/abstractoauth/abstractoauth.pro new file mode 100644 index 0000000..f82032c --- /dev/null +++ b/tests/auto/abstractoauth/abstractoauth.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +CONFIG += testcase +TARGET = tst_abstractoauth +SOURCES += tst_abstractoauth.cpp + +QT = core core-private network networkauth networkauth-private testlib diff --git a/tests/auto/abstractoauth/tst_abstractoauth.cpp b/tests/auto/abstractoauth/tst_abstractoauth.cpp new file mode 100644 index 0000000..0faf06e --- /dev/null +++ b/tests/auto/abstractoauth/tst_abstractoauth.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <QtTest> +#include <QtNetwork> + +#include <QtNetworkAuth/qabstractoauth.h> + +#include <private/qabstractoauth_p.h> + +class tst_AbstractOAuth : public QObject +{ + Q_OBJECT + +private: + struct AbstractOAuth : QAbstractOAuth { + AbstractOAuth() : QAbstractOAuth(*new QAbstractOAuthPrivate(QUrl(), nullptr), nullptr) {} + + virtual QString clientIdentifier() const override { return QString(); } + virtual void setClientIdentifier(const QString &) override {} + virtual QString token() const override { return QString(); } + virtual void setToken(const QString &) override {} + virtual QNetworkReply *head(const QUrl &, const QVariantMap &) override { return nullptr; } + virtual QNetworkReply *get(const QUrl &, const QVariantMap &) override { return nullptr; } + virtual QNetworkReply *post(const QUrl &, const QVariantMap &) override { return nullptr; } + virtual QNetworkReply *deleteResource(const QUrl &, const QVariantMap &) override + { + return nullptr; + } + virtual void grant() override {} + }; + +private Q_SLOTS: + void authorizationUrlSignal(); +}; + +void tst_AbstractOAuth::authorizationUrlSignal() +{ + AbstractOAuth obj; + QUrl expectedValue = QUrl("http://example.net/"); + const QUrl defaultValue = obj.authorizationUrl(); + QVERIFY(expectedValue != defaultValue); + bool emitted = false; + connect(&obj, &QAbstractOAuth::authorizationUrlChanged, [&](const QUrl &value) { + QCOMPARE(expectedValue, value); + emitted = true; + }); + obj.setAuthorizationUrl(expectedValue); + QVERIFY(emitted); +} + +QTEST_MAIN(tst_AbstractOAuth) +#include "tst_abstractoauth.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 4bee3ee..41f3293 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -5,3 +5,7 @@ SUBDIRS += \ oauth1 \ oauth1signature \ oauthhttpserverreplyhandler + +qtConfig(private_tests) { + SUBDIRS += abstractoauth +} diff --git a/tests/auto/oauth1/tst_oauth1.cpp b/tests/auto/oauth1/tst_oauth1.cpp index 0983bf3..1f604ce 100644 --- a/tests/auto/oauth1/tst_oauth1.cpp +++ b/tests/auto/oauth1/tst_oauth1.cpp @@ -74,11 +74,62 @@ public: int waitForFinish(QNetworkReplyPtr &reply); void fillParameters(QVariantMap *parameters, const QUrlQuery &query); + template<class Type> + struct PropertyTester + { + typedef Type InnerType; + typedef void(QOAuth1::*ConstSignalType)(const Type &); + typedef void(QOAuth1::*SignalType)(Type); + typedef QVector<std::function<void(Type *, QOAuth1 *object)>> SetterFunctions; + + private: + // Each entry in setters should set its first parameter to an expected value + // and act on its second, a QOAuth1 object, to trigger signal; this + // function shall check that signal is passed the value the setter previously + // told us to expect. + template<class SignalType> + static void runImpl(SignalType signal, const SetterFunctions &setters) + { + QOAuth1 obj; + Type expectedValue; + QSignalSpy spy(&obj, signal); + connect(&obj, signal, [&](const Type &value) { + QCOMPARE(expectedValue, value); + }); + for (const auto &setter : setters) { + const auto previous = expectedValue; + setter(&expectedValue, &obj); + QVERIFY(previous != expectedValue); // To check if the value was modified + } + QCOMPARE(spy.count(), setters.size()); // The signal should be emitted + } + + public: + + static void run(ConstSignalType signal, const SetterFunctions &setters) + { + runImpl(signal, setters); + } + + static void run(SignalType signal, const SetterFunctions &setters) + { + runImpl(signal, setters); + } + }; + public Q_SLOTS: void finished(); void gotError(); private Q_SLOTS: + void clientIdentifierSignal(); + void clientSharedSecretSignal(); + void tokenSecretSignal(); + void temporaryCredentialsUrlSignal(); + void temporaryTokenCredentialsUrlSignal(); + void tokenCredentialsUrlSignal(); + void signatureMethodSignal(); + void getToken_data(); void getToken(); @@ -132,6 +183,103 @@ void tst_OAuth1::gotError() disconnect(QObject::sender(), SIGNAL(finished()), this, 0); } +void tst_OAuth1::clientIdentifierSignal() +{ + using PropertyTester = PropertyTester<QString>; + PropertyTester::SetterFunctions setters { + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setClientIdentifier"; + object->setClientIdentifier(*expectedValue); + }, + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setClientCredentials"; + object->setClientCredentials(qMakePair(*expectedValue, QString())); + } + }; + PropertyTester::run(&QOAuth1::clientIdentifierChanged, setters); +} + +void tst_OAuth1::clientSharedSecretSignal() +{ + using PropertyTester = PropertyTester<QString>; + PropertyTester::SetterFunctions setters { + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setClientSharedSecret"; + object->setClientSharedSecret(*expectedValue); + }, + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setClientCredentials"; + object->setClientCredentials(qMakePair(QString(), *expectedValue)); + } + }; + PropertyTester::run(&QOAuth1::clientSharedSecretChanged, setters); +} + +void tst_OAuth1::tokenSecretSignal() +{ + using PropertyTester = PropertyTester<QString>; + PropertyTester::SetterFunctions setters { + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setToken"; + object->setToken(*expectedValue); + }, + [](QString *expectedValue, QOAuth1 *object) { + *expectedValue = "setTokenCredentials"; + object->setTokenCredentials(qMakePair(*expectedValue, QString())); + } + }; + PropertyTester::run(&QOAuth1::tokenChanged, setters); +} + +void tst_OAuth1::temporaryCredentialsUrlSignal() +{ + using PropertyTester = PropertyTester<QUrl>; + PropertyTester::SetterFunctions setters { + [](QUrl *expectedValue, QOAuth1 *object) { + *expectedValue = QUrl("http://example.net/"); + object->setTemporaryCredentialsUrl(*expectedValue); + } + }; + PropertyTester::run(&QOAuth1::temporaryCredentialsUrlChanged, setters); +} + +void tst_OAuth1::temporaryTokenCredentialsUrlSignal() +{ + using PropertyTester = PropertyTester<QUrl>; + PropertyTester::SetterFunctions setters { + [](QUrl *expectedValue, QOAuth1 *object) { + *expectedValue = QUrl("http://example.net/"); + object->setTemporaryCredentialsUrl(*expectedValue); + } + }; + PropertyTester::run(&QOAuth1::temporaryCredentialsUrlChanged, setters); +} + +void tst_OAuth1::tokenCredentialsUrlSignal() +{ + using PropertyTester = PropertyTester<QUrl>; + PropertyTester::SetterFunctions setters { + [](QUrl *expectedValue, QOAuth1 *object) { + *expectedValue = QUrl("http://example.net/"); + object->setTokenCredentialsUrl(*expectedValue); + } + }; + PropertyTester::run(&QOAuth1::tokenCredentialsUrlChanged, setters); +} + +void tst_OAuth1::signatureMethodSignal() +{ + using PropertyTester = PropertyTester<QOAuth1::SignatureMethod>; + PropertyTester::SetterFunctions setters { + [](PropertyTester::InnerType *expectedValue, QOAuth1 *object) { + QVERIFY(object->signatureMethod() != QOAuth1::SignatureMethod::PlainText); + *expectedValue = QOAuth1::SignatureMethod::PlainText; + object->setSignatureMethod(*expectedValue); + } + }; + PropertyTester::run(&QOAuth1::signatureMethodChanged, setters); +} + void tst_OAuth1::getToken_data() { QTest::addColumn<StringPair>("clientCredentials"); |