AuthorizationResultPtr OAuth2Response::parseAuthorizeResponse(const String& webAuthenticationResult, CallStatePtr/* callState*/)
{
    Logger::info(Tag(), "parseAuthorizeResponse");
    Logger::hidden(Tag(), "webAuthenticationResult: " + webAuthenticationResult);

    AuthorizationResultPtr parseResult = nullptr;

    QUrl url(webAuthenticationResult.data());
    if (url.hasQuery())
    {
        QUrlQuery query = QUrlQuery(url);
        if( query.hasQueryItem(OAuthConstants::oAuthReservedClaim().Code.data()) )
        {
            parseResult = std::make_shared<AuthorizationResult>(query.queryItemValue(OAuthConstants::oAuthReservedClaim().Code.data()).toStdString());
        }
        else if( query.hasQueryItem(OAuthConstants::oAuthReservedClaim().Error.data()) )
        {
            String error = query.queryItemValue(OAuthConstants::oAuthReservedClaim().Error.data()).toStdString();
            String errorDesc = query.hasQueryItem(OAuthConstants::oAuthReservedClaim().ErrorDescription.data())
                ? query.queryItemValue(OAuthConstants::oAuthReservedClaim().ErrorDescription.data(), QUrl::FullyDecoded).toStdString()
                : "";
            parseResult = std::make_shared<AuthorizationResult>(
                error,
                StringUtils::replaceAll(errorDesc, '+', ' '));
        }
        else
        {
            parseResult = std::make_shared<AuthorizationResult>(
                Constants::rmsauthError().AuthenticationFailed,
                Constants::rmsauthErrorMessage().AuthorizationServerInvalidResponse);
        }
    }

    return parseResult;
}
QJsonObject RequestsManager::autorisation( const SQLMgr &db, const QUrlQuery &urlQuery )
{
    UserControl userControl = UserControl::instance();
    QString login = urlQuery.queryItemValue( "login" ),
        password = urlQuery.queryItemValue( "password" );

    if( db.auth( login, password ) )
    {
        /*db.select( "USERS", { "name", } );*/

        User user( login );
        QString token = userControl.pushUser( user );

        QJsonObject response{
            { "token", token }
        };
        QJsonObject obj{
            { "code", 200 },
            { "response", response }
        };
        return obj;
    }
    QJsonObject failed{
        { "autirisation", "failed" }
    };
    return failed;
}
Beispiel #3
0
CommandLineParameters parseCommandLine(const QStringList &arguments)
{
    QCommandLineParser parser;
    parser.setApplicationDescription(QObject::tr("Zeal - Offline documentation browser."));
    parser.addHelpOption();
    parser.addVersionOption();

    /// TODO: [Qt 5.4] parser.addOption({{"f", "force"}, "Force the application run."});
    parser.addOption(QCommandLineOption({QStringLiteral("f"), QStringLiteral("force")},
                                        QObject::tr("Force the application run.")));
    /// TODO: [0.2.0] Remove --query support
    parser.addOption(QCommandLineOption({QStringLiteral("q"), QStringLiteral("query")},
                                        QObject::tr("[DEPRECATED] Query <search term>."),
                                        QStringLiteral("term")));
#ifdef Q_OS_WIN32
    parser.addOption(QCommandLineOption({QStringLiteral("register")},
                                        QObject::tr("Register protocol handlers")));
    parser.addOption(QCommandLineOption({QStringLiteral("unregister")},
                                        QObject::tr("Unregister protocol handlers")));
#endif
    parser.addPositionalArgument(QStringLiteral("url"), QObject::tr("dash[-plugin]:// URL"));
    parser.process(arguments);

    CommandLineParameters clParams;
    clParams.force = parser.isSet(QStringLiteral("force"));

#ifdef Q_OS_WIN32
    clParams.registerProtocolHandlers = parser.isSet(QStringLiteral("register"));
    clParams.unregisterProtocolHandlers = parser.isSet(QStringLiteral("unregister"));

    if (clParams.registerProtocolHandlers && clParams.unregisterProtocolHandlers) {
        QTextStream(stderr) << QObject::tr("Parameter conflict: --register and --unregister.\n");
        ::exit(EXIT_FAILURE);
    }
#endif

    if (parser.isSet(QStringLiteral("query"))) {
        clParams.query.setQuery(parser.value(QStringLiteral("query")));
    } else {
        /// TODO: Support dash-feed:// protocol
        const QString arg
                = QUrl::fromPercentEncoding(parser.positionalArguments().value(0).toUtf8());
        if (arg.startsWith(QLatin1String("dash:"))) {
            clParams.query.setQuery(stripParameterUrl(arg, QStringLiteral("dash")));
        } else if (arg.startsWith(QLatin1String("dash-plugin:"))) {
            const QUrlQuery urlQuery(stripParameterUrl(arg, QStringLiteral("dash-plugin")));
            const QString keys = urlQuery.queryItemValue(QStringLiteral("keys"));
            if (!keys.isEmpty())
                clParams.query.setKeywords(keys.split(QLatin1Char(',')));
            clParams.query.setQuery(urlQuery.queryItemValue(QStringLiteral("query")));
        } else {
            clParams.query.setQuery(arg);
        }
    }

    return clParams;
}
void tst_QUrlQuery::multiAddRemove()
{
    QUrlQuery query;

    {
        // one item, two values
        query.addQueryItem("a", "b");
        query.addQueryItem("a", "c");
        QVERIFY(!query.isEmpty());
        QVERIFY(query.hasQueryItem("a"));

        // returns the first one
        QVERIFY(query.queryItemValue("a") == "b");

        // order is the order we set them in
        QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c");
    }

    {
        // add another item, two values
        query.addQueryItem("A", "B");
        query.addQueryItem("A", "C");
        QVERIFY(query.hasQueryItem("A"));
        QVERIFY(query.hasQueryItem("a"));

        QVERIFY(query.queryItemValue("a") == "b");
        QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c");
        QVERIFY(query.queryItemValue("A") == "B");
        QVERIFY(query.allQueryItemValues("A") == QStringList() << "B" << "C");
    }

    {
        // remove one of the original items
        query.removeQueryItem("a");
        QVERIFY(query.hasQueryItem("a"));

        // it must have removed the first one
        QVERIFY(query.queryItemValue("a") == "c");
    }

    {
        // remove the items we added later
        query.removeAllQueryItems("A");
        QVERIFY(!query.isEmpty());
        QVERIFY(!query.hasQueryItem("A"));
    }

    {
        // add one element to the current, then remove them
        query.addQueryItem("a", "d");
        query.removeAllQueryItems("a");
        QVERIFY(!query.hasQueryItem("a"));
        QVERIFY(query.isEmpty());
    }
}
Beispiel #5
0
void Utils::testIncludeUrlParams() {
    QUrl urla(QString("http://example.com"));

    QHash<QString, QString> params;
    params.insert("simple", "c");
    params.insert("withspecial", "a?b");
    params.insert("withspace", "a b");
    params.insert("username", "a123fx b");
    params.insert("password", "!@#+-$%^12&*()qweqesaf\"';`~");
    params.insert("withplus", "a+b");

    QUrl urlb = ::includeQueryParams(urla, params);

    QVERIFY(urla.scheme() == urlb.scheme());
    QVERIFY(urla.host() == urlb.host());

    Q_FOREACH (const QString& key, params.keys()) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
        QString encoded_key = QUrl::toPercentEncoding(key);
        QString encoded_value = QUrl::toPercentEncoding(params[encoded_key]);
        QUrlQuery query = QUrlQuery(urlb.query());
        QVERIFY(query.queryItemValue(encoded_key, QUrl::FullyEncoded) == encoded_value);
#else
        QVERIFY(urlb.queryItemValue(key) == params[key]);
#endif
    }
}
    void OpenLinksFromFileSystem::AnchorClicked(const QUrl & url)
    {
        #ifdef Q_OS_WIN
            if(url.host().contains("shelexecute"))
            {
                QUrlQuery q;
                q.setQuery(url.query());
                QString cmd = q.queryItemValue("cmd",QUrl::FullyDecoded);
                QString arg = q.queryItemValue("arg",QUrl::FullyDecoded);

                LPCWSTR s1 = (LPCWSTR)cmd.utf16();
                LPCWSTR s2 = NULL;
                if(q.hasQueryItem("arg"))
                    s2 = (LPCWSTR)arg.utf16();

                ShellExecute(NULL,NULL,s1,s2,NULL,SW_RESTORE);

            }else
        #endif
        {
            QFileInfo info(url.toString());
            QDesktopServices::openUrl(QUrl::fromLocalFile(info.absoluteFilePath()));

        }

    }
Beispiel #7
0
/*!
 * Image {
 *     source: "image://avatar/path?name=icon-name"
 * }
 *
 * Image {
 *     source: "image://avatar/path?size=64&name=icon-name"
 * }
 */
QPixmap QuickAvatarProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
	const QUrl url(QStringLiteral("file:///") + id);
	const QUrlQuery query(url.query());
	const QString filePath = url.path();
	const QString iconName = query.queryItemValue(QStringLiteral("name"));
	const QString iconSize = query.queryItemValue(QStringLiteral("size"));

	QSize tmp;
	if (!size)
		size = &tmp;

	bool ok = false;
	int iconSizeValue = iconSize.toInt(&ok);
	if (ok)
		*size = QSize(iconSizeValue, iconSizeValue);
	else if (requestedSize.width() > 0)
		*size = requestedSize;
	else
		*size = QSize(128, 128);

	QIcon icon = Icon(iconName);

	if (filePath.size() > 1)
		icon = AvatarFilter::icon(filePath, icon);

	return icon.pixmap(*size);
}
void tst_QUrlQuery::old_queryItems()
{
    // test imported from old tst_qurl.cpp
    QUrlQuery url;

    QList<QPair<QString, QString> > newItems;
    newItems += qMakePair(QString("1"), QString("a"));
    newItems += qMakePair(QString("2"), QString("b"));
    newItems += qMakePair(QString("3"), QString("c"));
    newItems += qMakePair(QString("4"), QString("a b"));
    newItems += qMakePair(QString("5"), QString("&"));
    newItems += qMakePair(QString("foo bar"), QString("hello world"));
    newItems += qMakePair(QString("foo+bar"), QString("hello+world"));
    newItems += qMakePair(QString("tex"), QString("a + b = c"));
    url.setQueryItems(newItems);
    QVERIFY(!url.isEmpty());

    QList<QPair<QString, QString> > setItems = url.queryItems();
    QVERIFY(newItems == setItems);

    url.addQueryItem("1", "z");

#if 0
    // undefined behaviour in the new QUrlQuery

    QVERIFY(url.hasQueryItem("1"));
    QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "a");

    url.addQueryItem("1", "zz");

    QStringList expected;
    expected += "a";
    expected += "z";
    expected += "zz";
    QCOMPARE(url.allQueryItemValues("1"), expected);

    url.removeQueryItem("1");
    QCOMPARE(url.allQueryItemValues("1").size(), 2);
    QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "z");
#endif

    url.removeAllQueryItems("1");
    QVERIFY(!url.hasQueryItem("1"));

    QCOMPARE(url.queryItemValue("4").toLatin1().constData(), "a b");
    QCOMPARE(url.queryItemValue("5").toLatin1().constData(), "&");
    QCOMPARE(url.queryItemValue("tex").toLatin1().constData(), "a + b = c");
    QCOMPARE(url.queryItemValue("foo bar").toLatin1().constData(), "hello world");

    //url.setUrl("http://www.google.com/search?q=a+b");
    url.setQuery("q=a+b");
    QCOMPARE(url.queryItemValue("q"), QString("a+b"));

    //url.setUrl("http://www.google.com/search?q=a=b"); // invalid, but should be tolerated
    url.setQuery("q=a=b");
    QCOMPARE(url.queryItemValue("q"), QString("a=b"));
}
void TestAwsSignatureV2::adornRequest()
{
    QFETCH(QNetworkRequest, request);
    QFETCH(QString, accessKeyId);
    QFETCH(QCryptographicHash::Algorithm, algorithm);
    QFETCH(QString, signatureMethod);

    const AwsBasicCredentials credentials(accessKeyId, QString());

    AwsSignatureV2 signature(algorithm);
    signature.d_func()->adornRequest(request, credentials);
    const QUrlQuery query(request.url());

    QVERIFY(query.hasQueryItem(QLatin1String("AWSAccessKeyId")));
    QVERIFY(query.hasQueryItem(QLatin1String("SignatureMethod")));
    QVERIFY(query.hasQueryItem(QLatin1String("SignatureVersion")));
    QVERIFY(query.hasQueryItem(QLatin1String("Timestamp")));

    QCOMPARE(query.queryItemValue(QLatin1String("AWSAccessKeyId")), accessKeyId);
    QCOMPARE(query.queryItemValue(QLatin1String("SignatureMethod")), signatureMethod);
    QCOMPARE(query.queryItemValue(QLatin1String("SignatureVersion")), QString::fromLatin1("2"));
}
QJsonObject RequestsManager::report( const SQLMgr &db, const QString &request, const QUrlQuery &query )
{
    IdTitleMap  List;
    QJsonObject obj;
    if( request.startsWith( "/get" ) )          // /getProfessionsLIst
    {
        QString listName = request.right( 4 );

        List = listName.startsWith( "lesson", Qt::CaseInsensitive ) ?   // íàâåðíîå ýòî óæàñíî ÷èòàåòñÿ, íî ðàîòàåò
            Lesson::getLessonsList( db, query.queryItemValue( "id" ) ) :

            listName.startsWith( "prof", Qt::CaseInsensitive ) ?
            Profession::getProfList( db ) :

            listName.startsWith( "theme", Qt::CaseInsensitive ) ?
            Theme::getThemeList( db, query.queryItemValue( "id" ) ) :
            IdTitleMap();

        obj = JsonFormat::lessonsListToJsonObj( List );
    }
    //TODO TcpSocket::report( obj );
    return obj;
}
Beispiel #11
0
int SM_QDropbox::requestAccessToken(bool blocking)
{
    clearError();

    QUrl url;
    url.setUrl(apiurl.toString());

    QUrlQuery query;
    query.addQueryItem("oauth_consumer_key",_appKey);
    query.addQueryItem("oauth_nonce", nonce);
    query.addQueryItem("oauth_signature_method", signatureMethodString());
    query.addQueryItem("oauth_timestamp", QString::number(timestamp));
    query.addQueryItem("oauth_token", oauthToken);
    query.addQueryItem("oauth_version", _version);

    url.setPath(QString("/%1/oauth/access_token").
                arg(_version.left(1)));

#ifdef SM_QTDROPBOX_DEBUG
    qDebug() << "requestToken = " << query.queryItemValue("oauth_token");
#endif

    QString signature = oAuthSign(url);
    query.addQueryItem("oauth_signature", QUrl::toPercentEncoding(signature));

    url.setQuery(query);

    QString dataString = url.toString(QUrl::RemoveScheme|QUrl::RemoveAuthority|
                                      QUrl::RemovePath).mid(1);
#ifdef SM_QTDROPBOX_DEBUG
    qDebug() << "dataString = " << dataString << endl;
#endif

    QByteArray postData;
    postData.append(dataString.toUtf8());

    QUrl xQuery(url.toString(QUrl::RemoveQuery));
    int reqnr = sendRequest(xQuery, "POST", postData);

    if(blocking)
    {
        requestMap[reqnr].type = SM_DROPBOX_REQ_BACCTOK;
        startEventLoop();
    }
    else
        requestMap[reqnr].type = SM_DROPBOX_REQ_ACCTOKN;

    return reqnr;
}
Beispiel #12
0
	bool VkAuthManager::CheckReply (QUrl location)
	{
		if (location.path () != "/blank.html")
			return CheckError (location);

		location = QUrl::fromEncoded (location.toEncoded ().replace ('#', '?'));
#if QT_VERSION < 0x050000
		Token_ = location.queryItemValue ("access_token");
		ValidFor_ = location.queryItemValue ("expires_in").toInt ();
#else
		const QUrlQuery query { location };
		Token_ = query.queryItemValue ("access_token");
		ValidFor_ = query.queryItemValue ("expires_in").toInt ();
#endif
		ReceivedAt_ = QDateTime::currentDateTime ();
		qDebug () << Q_FUNC_INFO << Token_ << ValidFor_;
		IsRequesting_ = false;

		InvokeQueues (Token_);
		emit gotAuthKey (Token_);
		emit justAuthenticated ();

		return true;
	}
Beispiel #13
0
/**
 * @brief   Set a query item, checking for existing values first.
 *
 * This function is a light wrapper around QUrlQuery::addQueryItem() that first
 * checks for existing values.  Existing values will not be overwritten, instead
 * if existing values are found, this function will simply check if the exsting
 * value matches the desired \a value, and if not, will return `false` and
 * optionally (according to \a warnOnNonIdenticalDuplicate) issue a qWarning().
 *
 * Typically, when setting something that must be a specific value, such as an
 * access key ID, \a warnOnNonIdenticalDuplicate would be `true`. However, when
 * setting query items as a fall-back default, such as a current timestamp,
 * \a warnOnNonIdenticalDuplicate would typically be set to `false`.
 *
 * @param   query  URL query to add the query item to.
 * @param   key    Query item key to add to \a query.
 * @param   value  Query item value to add to \a query.
 * @param   warnOnNonIdenticalDuplicate  If `true`, and an exisiting \a key
 *          value is found in \a query that has a value other than \a value,
 *          then a qWarning() is issued, otherwise the duplicate is silently
 *          ignored.
 *
 * @return  `true` if the query item was set successfully or was already set to
 *          the requested value previously, `false` otherwise.
 */
bool AwsAbstractSignaturePrivate::setQueryItem(QUrlQuery &query, const QString &key, const QString &value,
                                               const bool warnOnNonIdenticalDuplicate) const
{
    if (query.hasQueryItem(key)) {
        const QString existingValue = query.queryItemValue(key, QUrl::FullyEncoded);
        const bool existingQueryItemIsIdentical = (existingValue == value);
        if ((warnOnNonIdenticalDuplicate) && (!existingQueryItemIsIdentical)) {
            qWarning() << "AwsAbstractSignature::setQueryItem Not overwriting existing value for key"
                       << key << ':' << existingValue;
        }
        return existingQueryItemIsIdentical;
    }
    query.addQueryItem(key, value);
    return true;
}
Beispiel #14
0
QQuickWebEngineView *GameUpQtPrivate::webView() const {
#else
QQuickWebView *GameUpQt::webView() const {
#endif
    return m_webView;
}

#ifdef QT_WEBVIEW_WEBENGINE_BACKEND
void GameUpQtPrivate::setWebView(QQuickWebEngineView *webView) {
#else
void GameUpQtPrivate::setWebView(QQuickWebView *webView) {
#endif
    m_webView = webView;
}

Gamer *GameUpQtPrivate::getGamer() {
    return &m_gamer;
}

QString GameUpQtPrivate::getLeaderboardID() const {
    return m_leaderboardID;
}

void GameUpQtPrivate::setLeaderboardID(const QString &leaderboardID) {
    m_leaderboardID = leaderboardID;
}

Leaderboard *GameUpQtPrivate::getLeaderboard(const QString &id) {
    return m_leaderboards[id];
}

bool GameUpQtPrivate::getAsyncMode() const {
    return m_asyncMode;
}

void GameUpQtPrivate::setAsyncMode(bool asyncMode) {
    m_asyncMode = asyncMode;
}


QNetworkReply::NetworkError GameUpQtPrivate::getLasterror() const {
    return lasterror;
}

QString GameUpQtPrivate::getLastToken() const {
    return m_lastToken;
}

QQmlListProperty<Leaderboard> GameUpQtPrivate::leaderboards() {
    QList<Leaderboard*> l = m_leaderboards.values();
    return QQmlListProperty<Leaderboard>(this, l);
}

#ifdef QT_WEBVIEW_WEBENGINE_BACKEND
void GameUpQtPrivate::webViewLoadingProgress(QQuickWebEngineLoadRequest *loadRequest) {

    qDebug() << "loadrequest" << loadRequest->url() << loadRequest->errorCode() << loadRequest->status();
    QUrlQuery query = QUrlQuery(loadRequest->url());
    if (query.hasQueryItem("token")) {
        m_lastToken = query.queryItemValue("token");
    }
    if (!m_lastToken.isEmpty()
            || loadRequest->errorCode() != 0
            || loadRequest->status() == QQuickWebEngineView::LoadFailedStatus
            || query.isEmpty()) {
        disconnect(m_webView, &QQuickWebEngineView::loadingChanged, this, &GameUpQtPrivate::webViewLoadingProgress);
        if (!m_asyncMode && loop.isRunning())
            loop.quit();
        emit reqComplete(GameUpQt::Login);
    }
}
Beispiel #15
0
bool WulforUtil::openUrl(const QString &url){
    if (url.startsWith("http://") || url.startsWith("www.") || url.startsWith(("ftp://")) || url.startsWith("https://")){
        if (!SETTING(MIME_HANDLER).empty())
            QProcess::startDetached(_q(SETTING(MIME_HANDLER)), QStringList(url));
        else
            QDesktopServices::openUrl(QUrl::fromEncoded(url.toUtf8()));
    }
    else if (url.startsWith("adc://") || url.startsWith("adcs://")){
        MainWindow::getInstance()->newHubFrame(url, "UTF-8");
    }
    else if (url.startsWith("dchub://") || url.startsWith("nmdcs://")){
        MainWindow::getInstance()->newHubFrame(url, WSGET(WS_DEFAULT_LOCALE));
    }
    else if (url.startsWith("magnet:") && url.contains("urn:tree:tiger")){
        QString magnet = url;
        Magnet *m = new Magnet(MainWindow::getInstance());

        m->setLink(magnet);
        m->exec();

        m->deleteLater();
    }
    else if (url.startsWith("magnet:")){
        const QString magnet = url;

#if QT_VERSION >= 0x050000
        QUrlQuery u;
#else
        QUrl u;
#endif

        if (!magnet.contains("+")) {
#if QT_VERSION >= 0x050000
                u.setQuery(magnet.toUtf8());
#else
                u.setEncodedUrl(magnet.toUtf8());
#endif
        } else {
            QString _l = magnet;

            _l.replace("+", "%20");
#if QT_VERSION >= 0x050000
                u.setQuery(_l.toUtf8());
#else
                u.setEncodedUrl(_l.toUtf8());
#endif
        }

        if (u.hasQueryItem("kt")) {
            QString keywords = u.queryItemValue("kt");
            QString hub = u.hasQueryItem("xs")? u.queryItemValue("xs") : "";

            if (!(hub.startsWith("dchub://", Qt::CaseInsensitive) ||
                  hub.startsWith("nmdcs://", Qt::CaseInsensitive) ||
                  hub.startsWith("adc://", Qt::CaseInsensitive) ||
                  hub.startsWith("adcs://", Qt::CaseInsensitive)) && !hub.isEmpty())
                hub.prepend("dchub://");

            if (keywords.isEmpty())
                return false;

            if (!hub.isEmpty())
                WulforUtil::openUrl(hub);

            SearchFrame *sfr = ArenaWidgetFactory().create<SearchFrame>();
            sfr->fastSearch(keywords, false);
        }
        else {
            if (!SETTING(MIME_HANDLER).empty())
                QProcess::startDetached(_q(SETTING(MIME_HANDLER)), QStringList(url));
            else
                QDesktopServices::openUrl(QUrl::fromEncoded(url.toUtf8()));
        }
    }
    else
        return false;

    return true;
}
void tst_QUrlQuery::constructing()
{
    QUrlQuery empty;
    QVERIFY(empty.isEmpty());
    QCOMPARE(empty.queryPairDelimiter(), QUrlQuery::defaultQueryPairDelimiter());
    QCOMPARE(empty.queryValueDelimiter(), QUrlQuery::defaultQueryValueDelimiter());
    // undefined whether it is detached, but don't crash
    QVERIFY(empty.isDetached() || !empty.isDetached());

    empty.clear();
    QVERIFY(empty.isEmpty());

    {
        QUrlQuery copy(empty);
        QVERIFY(copy.isEmpty());
        QVERIFY(!copy.isDetached());
        QVERIFY(copy == empty);
        QVERIFY(!(copy != empty));

        copy = empty;
        QVERIFY(copy == empty);

        copy = QUrlQuery();
        QVERIFY(copy == empty);
    }
    {
        QUrlQuery copy(emptyQuery());
        QVERIFY(copy == empty);
    }

    QVERIFY(!empty.hasQueryItem("a"));
    QVERIFY(empty.queryItemValue("a").isEmpty());
    QVERIFY(empty.allQueryItemValues("a").isEmpty());

    QVERIFY(!empty.hasQueryItem(""));
    QVERIFY(empty.queryItemValue("").isEmpty());
    QVERIFY(empty.allQueryItemValues("").isEmpty());

    QVERIFY(!empty.hasQueryItem(QString()));
    QVERIFY(empty.queryItemValue(QString()).isEmpty());
    QVERIFY(empty.allQueryItemValues(QString()).isEmpty());

    QVERIFY(empty.queryItems().isEmpty());

    QUrlQuery other;
    other.addQueryItem("a", "b");
    QVERIFY(!other.isEmpty());
    QVERIFY(other.isDetached());
    QVERIFY(other != empty);
    QVERIFY(!(other == empty));

    QUrlQuery copy(other);
    QVERIFY(copy == other);

    copy.clear();
    QVERIFY(copy.isEmpty());
    QVERIFY(copy != other);

    copy = other;
    QVERIFY(!copy.isEmpty());
    QVERIFY(copy == other);

    copy = QUrlQuery();
    QVERIFY(copy.isEmpty());

    empty.setQueryDelimiters('(', ')');
    QCOMPARE(empty.queryValueDelimiter(), QChar(QLatin1Char('(')));
    QCOMPARE(empty.queryPairDelimiter(), QChar(QLatin1Char(')')));

    QList<QPair<QString, QString> > query;
    query += qMakePair(QString("type"), QString("login"));
    query += qMakePair(QString("name"), QString::fromUtf8("åge nissemannsen"));
    query += qMakePair(QString("ole&du"), QString::fromUtf8("anne+jørgen=sant"));
    query += qMakePair(QString("prosent"), QString("%"));
    copy.setQueryItems(query);
    QVERIFY(!copy.isEmpty());
}
void tst_QUrlQuery::addRemove()
{
    QUrlQuery query;

    {
        // one item
        query.addQueryItem("a", "b");
        QVERIFY(!query.isEmpty());
        QVERIFY(query.hasQueryItem("a"));
        QCOMPARE(query.queryItemValue("a"), QString("b"));
        QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");

        QList<QPair<QString, QString> > allItems = query.queryItems();
        QCOMPARE(allItems.count(), 1);
        QCOMPARE(allItems.at(0).first, QString("a"));
        QCOMPARE(allItems.at(0).second, QString("b"));
    }

    QUrlQuery original = query;

    {
        // two items
        query.addQueryItem("c", "d");
        QVERIFY(query.hasQueryItem("a"));
        QCOMPARE(query.queryItemValue("a"), QString("b"));
        QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
        QVERIFY(query.hasQueryItem("c"));
        QCOMPARE(query.queryItemValue("c"), QString("d"));
        QCOMPARE(query.allQueryItemValues("c"), QStringList() << "d");

        QList<QPair<QString, QString> > allItems = query.queryItems();
        QCOMPARE(allItems.count(), 2);
        QVERIFY(allItems.contains(qItem("a", "b")));
        QVERIFY(allItems.contains(qItem("c", "d")));

        QVERIFY(query != original);
        QVERIFY(!(query == original));
    }

    {
        // remove an item that isn't there
        QUrlQuery copy = query;
        query.removeQueryItem("e");
        QCOMPARE(query, copy);
    }

    {
        // remove an item
        query.removeQueryItem("c");
        QVERIFY(query.hasQueryItem("a"));
        QCOMPARE(query.queryItemValue("a"), QString("b"));
        QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");

        QList<QPair<QString, QString> > allItems = query.queryItems();
        QCOMPARE(allItems.count(), 1);
        QCOMPARE(allItems.at(0).first, QString("a"));
        QCOMPARE(allItems.at(0).second, QString("b"));

        QVERIFY(query == original);
        QVERIFY(!(query != original));
    }

    {
        // add an item with en empty value
        QString emptyButNotNull(0, Qt::Uninitialized);
        QVERIFY(emptyButNotNull.isEmpty());
        QVERIFY(!emptyButNotNull.isNull());

        query.addQueryItem("e", "");
        QVERIFY(query.hasQueryItem("a"));
        QCOMPARE(query.queryItemValue("a"), QString("b"));
        QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
        QVERIFY(query.hasQueryItem("e"));
        QCOMPARE(query.queryItemValue("e"), emptyButNotNull);
        QCOMPARE(query.allQueryItemValues("e"), QStringList() << emptyButNotNull);

        QList<QPair<QString, QString> > allItems = query.queryItems();
        QCOMPARE(allItems.count(), 2);
        QVERIFY(allItems.contains(qItem("a", "b")));
        QVERIFY(allItems.contains(qItem("e", emptyButNotNull)));

        QVERIFY(query != original);
        QVERIFY(!(query == original));
    }

    {
        // remove the items
        query.removeQueryItem("a");
        query.removeQueryItem("e");
        QVERIFY(query.isEmpty());
    }
}