diff options
Diffstat (limited to 'tests')
18 files changed, 234 insertions, 65 deletions
diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp index 88b4abe2e3..7564e3fc1f 100644 --- a/tests/auto/corelib/io/largefile/tst_largefile.cpp +++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp @@ -121,9 +121,7 @@ private slots: // Map/unmap large file void mapFile(); -#ifndef Q_OS_MAC void mapOffsetOverflow(); -#endif void closeFile() { largeFile.close(); } @@ -513,9 +511,9 @@ void tst_LargeFile::mapFile() } //Mac: memory-mapping beyond EOF may succeed but it could generate bus error on access -#ifndef Q_OS_MAC void tst_LargeFile::mapOffsetOverflow() { +#ifndef Q_OS_MAC // Out-of-range mappings should fail, and not silently clip the offset for (int i = 50; i < 63; ++i) { uchar *address = 0; @@ -529,8 +527,8 @@ void tst_LargeFile::mapOffsetOverflow() address = largeFile.map(((qint64)1 << i) + blockSize, blockSize); QVERIFY( !address ); } -} #endif +} QTEST_APPLESS_MAIN(tst_LargeFile) #include "tst_largefile.moc" diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index fbb21e4e9a..96be5065d6 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -193,6 +193,8 @@ private slots: void isReadable(); + void cdNonreadable(); + void cdBelowRoot(); private: @@ -1990,6 +1992,23 @@ void tst_QDir::isReadable() #endif } +void tst_QDir::cdNonreadable() +{ +#ifdef Q_OS_UNIX + if (::getuid() == 0) + QSKIP("Running this test as root doesn't make sense"); + + QDir dir; + QVERIFY(dir.mkdir("nonreadabledir2")); + QVERIFY(0 == ::chmod("nonreadabledir2", S_IWUSR | S_IXUSR)); + QVERIFY(dir.cd("nonreadabledir2")); + QVERIFY(!dir.isReadable()); + QVERIFY(dir.cd("..")); + QVERIFY(0 == ::chmod("nonreadabledir2", S_IRUSR | S_IWUSR | S_IXUSR)); + QVERIFY(dir.rmdir("nonreadabledir2")); +#endif +} + void tst_QDir::cdBelowRoot() { #if defined (Q_OS_UNIX) diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index d19f4379c7..20a31fc98f 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -52,7 +52,7 @@ #include <sys/types.h> #endif -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_BLACKBERRY) +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) #define Q_XDG_PLATFORM #endif @@ -289,9 +289,9 @@ void tst_qstandardpaths::testDataLocation() { // On all platforms, DataLocation should be GenericDataLocation / organization name / app name // This allows one app to access the data of another app. - // Blackberry OS and WinRT are an exception to this case, owing to the fact that + // Blackberry OS, Android and WinRT are an exception to this case, owing to the fact that // applications are sandboxed. -#if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_WINRT) +#if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT) const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/tst_qstandardpaths"); QCoreApplication::instance()->setOrganizationName("Qt"); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro index 1ff5546e5c..536a6b64de 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs SUBDIRS = qmimedatabase-xml -unix:!mac: SUBDIRS += qmimedatabase-cache +unix:!mac:!qnx: SUBDIRS += qmimedatabase-cache diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index b91de092e8..807dcf5cbe 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -944,6 +944,13 @@ void tst_QDate::fromStringDateFormat_data() QTest::newRow("iso2") << QDate(1999, 11, 14).toString(Qt::ISODate) << Qt::ISODate << QDate(1999, 11, 14); QTest::newRow("iso3") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1); QTest::newRow("iso3b") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1); + QTest::newRow("iso4") << QString("2000101101") << Qt::ISODate << QDate(); + QTest::newRow("iso5") << QString("2000/01/01") << Qt::ISODate << QDate(2000, 1, 1); + QTest::newRow("iso6") << QString("2000-01-01 blah") << Qt::ISODate << QDate(2000, 1, 1); + QTest::newRow("iso7") << QString("2000-01-011blah") << Qt::ISODate << QDate(); + QTest::newRow("iso8") << QString("2000-01-01blah") << Qt::ISODate << QDate(2000, 1, 1); + QTest::newRow("iso9") << QString("-001-01-01") << Qt::ISODate << QDate(); + QTest::newRow("iso10") << QString("99999-01-01") << Qt::ISODate << QDate(); // Test Qt::RFC2822Date format (RFC 2822). QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 0e7ac54a86..3bd8a7526e 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2787,6 +2787,13 @@ void tst_QDateTime::daylightTransitions() const void tst_QDateTime::timeZones() const { + QTimeZone invalidTz = QTimeZone("Vulcan/ShiKahr"); + QCOMPARE(invalidTz.isValid(), false); + QDateTime invalidDateTime = QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0), invalidTz); + QCOMPARE(invalidDateTime.isValid(), false); + QCOMPARE(invalidDateTime.date(), QDate(2000, 1, 1)); + QCOMPARE(invalidDateTime.time(), QTime(0, 0, 0)); + QTimeZone nzTz = QTimeZone("Pacific/Auckland"); // During Standard Time NZ is +12:00 diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 53caec4a64..59956e33cf 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -2042,6 +2042,9 @@ void tst_QVector::initializeList() QVector<QVector<T>> v3; v3 << v1 << (QVector<T>() << val4) << QVector<T>() << v1; QCOMPARE(v3, v2); + + QVector<T> v4({}); + QCOMPARE(v4.size(), 0); #endif } diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp index efc688f0b1..336564bc59 100644 --- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp @@ -642,7 +642,7 @@ void tst_QGuiVariant::writeToReadFromOldDataStream() dataFileStream.setVersion(QDataStream::Qt_4_9); QVariant readVariant; dataFileStream >> readVariant; - QVERIFY(readVariant.type() == QMetaType::QPolygonF); + QVERIFY(readVariant.userType() == QMetaType::QPolygonF); QCOMPARE(testVariant, readVariant); file.close(); } diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index 20f84060b6..94353703dc 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -124,10 +124,8 @@ private slots: void symetricConstructors(); void checkMultipleNames(); void checkMultipleCodes(); -#ifndef Q_OS_MAC void mnemonic_data(); void mnemonic(); -#endif void toString_data(); void toString(); void toStringFromKeycode_data(); @@ -148,10 +146,8 @@ private slots: void standardKeys_data(); void standardKeys(); void keyBindings(); -#if !defined (Q_OS_MAC) && !defined (Q_OS_WINCE) void translated_data(); void translated(); -#endif void i18nKeys_data(); void i18nKeys(); @@ -409,9 +405,11 @@ void tst_QKeySequence::keyBindings() QCOMPARE(bindings, expected); } -#ifndef Q_OS_MAC void tst_QKeySequence::mnemonic_data() { +#ifdef Q_OS_MAC + QSKIP("Test not applicable to Mac OS X"); +#endif QTest::addColumn<QString>("string"); QTest::addColumn<QString>("key"); QTest::addColumn<bool>("warning"); @@ -431,6 +429,7 @@ void tst_QKeySequence::mnemonic_data() void tst_QKeySequence::mnemonic() { +#ifndef Q_OS_MAC QFETCH(QString, string); QFETCH(QString, key); QFETCH(bool, warning); @@ -448,8 +447,8 @@ void tst_QKeySequence::mnemonic() QKeySequence res = QKeySequence(key); QCOMPARE(seq, res); -} #endif +} void tst_QKeySequence::toString_data() { @@ -738,9 +737,12 @@ void tst_QKeySequence::listFromString() QCOMPARE(QKeySequence::listFromString(strSequences), sequences); } -#if !defined (Q_OS_MAC) && !defined (Q_OS_WINCE) void tst_QKeySequence::translated_data() { +#if defined (Q_OS_MAC) || defined (Q_OS_WINCE) + QSKIP("Test not applicable"); +#endif + qApp->installTranslator(ourTranslator); qApp->installTranslator(qtTranslator); @@ -768,6 +770,7 @@ void tst_QKeySequence::translated_data() void tst_QKeySequence::translated() { +#if !defined (Q_OS_MAC) && !defined (Q_OS_WINCE) QFETCH(QString, transKey); QFETCH(QString, compKey); @@ -779,8 +782,8 @@ void tst_QKeySequence::translated() qApp->removeTranslator(ourTranslator); qApp->removeTranslator(qtTranslator); -} #endif +} void tst_QKeySequence::i18nKeys_data() { diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index b35c934680..4d5748b419 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6637,9 +6637,8 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); - QEXPECT_FAIL("http+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue); - QEXPECT_FAIL("https+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue); - + if (reply->error() == QNetworkReply::HostNotFoundError) + QSKIP("skip because of quirk in the old test server"); QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError); QCOMPARE(authSpy.count(), 0); QVERIFY(proxyAuthSpy.count() > 0); diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro index b7554b54d5..3b217f6e7b 100644 --- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro +++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro @@ -3,6 +3,7 @@ TARGET = tst_qhostinfo SOURCES += tst_qhostinfo.cpp +requires(contains(QT_CONFIG,private_tests)) QT = core-private network-private testlib wince*: { diff --git a/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro b/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro index 414486f82b..009d151e29 100644 --- a/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro +++ b/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro @@ -7,6 +7,7 @@ include(../platformsocketengine/platformsocketengine.pri) MOC_DIR=tmp +requires(contains(QT_CONFIG,private_tests)) QT = core-private network-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 3162165139..6eb20dd1f5 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1946,9 +1946,6 @@ void tst_QSslSocket::verifyMode() loop.exec(); QVERIFY(clientSocket.isEncrypted()); -#if (defined(UBUNTU_ONEIRIC) && defined(__x86_64__)) || defined(Q_OS_WIN) || defined(Q_OS_MAC) - QEXPECT_FAIL("", "QTBUG-24234", Abort); -#endif QVERIFY(server.socket->sslErrors().isEmpty()); } diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro index 320887637d..70a1ecd476 100644 --- a/tests/auto/tools/moc/moc.pro +++ b/tests/auto/tools/moc/moc.pro @@ -45,3 +45,6 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 # Ensure that plugin_metadata.h are moc-ed with some extra -M arguments: QMAKE_MOC_OPTIONS += -Muri=com.company.app -Muri=com.company.app.private +# Define macro on the command lines used in parse-defines.h +QMAKE_MOC_OPTIONS += "-DDEFINE_CMDLINE_EMPTY=" "\"-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)\"" + diff --git a/tests/auto/tools/moc/parse-defines.h b/tests/auto/tools/moc/parse-defines.h index aaadcef601..35934853f0 100644 --- a/tests/auto/tools/moc/parse-defines.h +++ b/tests/auto/tools/moc/parse-defines.h @@ -79,9 +79,16 @@ #define PD_ADD_SUFFIX(x) PD_DEFINE1(x,_SUFFIX) #define PD_DEFINE_ITSELF PD_ADD_SUFFIX(PD_DEFINE_ITSELF) +#ifndef Q_MOC_RUN +// macro defined on the command line (in tst_moc.pro) +#define DEFINE_CMDLINE_EMPTY +#define DEFINE_CMDLINE_SIGNAL void cmdlineSignal(const QMap<int, int> &i) +#endif + PD_BEGIN_NAMESPACE -class PD_CLASSNAME : public QObject +class DEFINE_CMDLINE_EMPTY PD_CLASSNAME DEFINE_CMDLINE_EMPTY + : public DEFINE_CMDLINE_EMPTY QObject DEFINE_CMDLINE_EMPTY { Q_OBJECT Q_CLASSINFO("TestString", PD_STRINGIFY(PD_CLASSNAME)) @@ -140,6 +147,9 @@ public slots: void PD_DEFINE_ITSELF(int) {} +signals: + DEFINE_CMDLINE_SIGNAL; + }; #undef QString diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 031884501c..72e24c282c 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -3042,6 +3042,9 @@ void tst_Moc::parseDefines() index = mo->indexOfSlot("PD_DEFINE_ITSELF_SUFFIX(int)"); QVERIFY(index != -1); + + index = mo->indexOfSignal("cmdlineSignal(QMap<int,int>)"); + QVERIFY(index != -1); } void tst_Moc::preprocessorOnly() diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp index baa3022919..51dd0852ee 100644 --- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp +++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp @@ -44,68 +44,72 @@ #include <QScrollBar> #include <QStyleOptionSlider> #include <QScrollArea> +#include <QScreen> + +static inline void centerOnScreen(QWidget *w, const QSize &size) +{ + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); +} + +static inline void centerOnScreen(QWidget *w) +{ + centerOnScreen(w, w->geometry().size()); +} class tst_QScrollBar : public QObject { Q_OBJECT -public slots: - void initTestCase(); - void cleanupTestCase(); - void hideAndShow(int action); - private slots: void scrollSingleStep(); void task_209492(); #ifndef QT_NO_WHEELEVENT void QTBUG_27308(); #endif - -private: - QScrollBar *testWidget; }; -void tst_QScrollBar::initTestCase() -{ - testWidget = new QScrollBar(Qt::Horizontal); - testWidget->resize(100, testWidget->height()); - testWidget->show(); -} - -void tst_QScrollBar::cleanupTestCase() -{ - delete testWidget; - testWidget = 0; -} +class SingleStepTestScrollBar : public QScrollBar { + Q_OBJECT +public: + explicit SingleStepTestScrollBar(Qt::Orientation o, QWidget *parent = 0) : QScrollBar(o, parent) {} -void tst_QScrollBar::hideAndShow(int) -{ - testWidget->hide(); - testWidget->show(); -} +public slots: + void hideAndShow() + { + hide(); + show(); + } +}; // Check that the scrollbar doesn't scroll after calling hide and show // from a slot connected to the scrollbar's actionTriggered signal. void tst_QScrollBar::scrollSingleStep() { - testWidget->setValue(testWidget->minimum()); - QCOMPARE(testWidget->value(), testWidget->minimum()); - connect(testWidget, SIGNAL(actionTriggered(int)), this, SLOT(hideAndShow(int))); + SingleStepTestScrollBar testWidget(Qt::Horizontal); + connect(&testWidget, &QAbstractSlider::actionTriggered, &testWidget, &SingleStepTestScrollBar::hideAndShow); + testWidget.resize(100, testWidget.height()); + centerOnScreen(&testWidget); + testWidget.show(); + QTest::qWaitForWindowExposed(&testWidget); + + testWidget.setValue(testWidget.minimum()); + QCOMPARE(testWidget.value(), testWidget.minimum()); // Get rect for the area to click on - const QStyleOptionSlider opt = qt_qscrollbarStyleOption(testWidget); - QRect sr = testWidget->style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarAddLine, testWidget); + const QStyleOptionSlider opt = qt_qscrollbarStyleOption(&testWidget); + QRect sr = testWidget.style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarAddLine, &testWidget); if (!sr.isValid()) QSKIP("SC_ScrollBarAddLine not valid"); - QTest::mouseClick(testWidget, Qt::LeftButton, Qt::NoModifier, QPoint(sr.x(), sr.y())); + QTest::mouseClick(&testWidget, Qt::LeftButton, Qt::NoModifier, QPoint(sr.x(), sr.y())); QTest::qWait(510); // initial delay is 500 for setRepeatAction - disconnect(testWidget, SIGNAL(actionTriggered(int)), 0, 0); + disconnect(&testWidget, &QAbstractSlider::actionTriggered, &testWidget, &SingleStepTestScrollBar::hideAndShow); #ifdef Q_OS_MAC QEXPECT_FAIL("", "This test fails on Mac OS X, see QTBUG-25272", Abort); #endif - QCOMPARE(testWidget->value(), testWidget->singleStep()); + QCOMPARE(testWidget.value(), testWidget.singleStep()); } void tst_QScrollBar::task_209492() @@ -123,8 +127,9 @@ void tst_QScrollBar::task_209492() MyScrollArea scrollArea; QScrollBar *verticalScrollBar = scrollArea.verticalScrollBar(); verticalScrollBar->setRange(0, 1000); + centerOnScreen(&scrollArea); scrollArea.show(); - QTest::qWait(300); + QTest::qWaitForWindowExposed(&scrollArea); QSignalSpy spy(verticalScrollBar, SIGNAL(actionTriggered(int))); QCOMPARE(scrollArea.scrollCount, 0); @@ -153,12 +158,18 @@ void tst_QScrollBar::QTBUG_27308() // https://bugreports.qt-project.org/browse/QTBUG-27308 // Check that a disabled scrollbar doesn't react on wheel events anymore - testWidget->setValue(testWidget->minimum()); - testWidget->setEnabled(false); - QWheelEvent event(testWidget->rect().center(), - -WHEEL_DELTA, Qt::NoButton, Qt::NoModifier, testWidget->orientation()); - qApp->sendEvent(testWidget, &event); - QCOMPARE(testWidget->value(), testWidget->minimum()); + QScrollBar testWidget(Qt::Horizontal); + testWidget.resize(100, testWidget.height()); + centerOnScreen(&testWidget); + testWidget.show(); + QTest::qWaitForWindowExposed(&testWidget); + + testWidget.setValue(testWidget.minimum()); + testWidget.setEnabled(false); + QWheelEvent event(testWidget.rect().center(), + -WHEEL_DELTA, Qt::NoButton, Qt::NoModifier, testWidget.orientation()); + qApp->sendEvent(&testWidget, &event); + QCOMPARE(testWidget.value(), testWidget.minimum()); } #endif diff --git a/tests/manual/qnetworkreply/main.cpp b/tests/manual/qnetworkreply/main.cpp index 2f47985261..fe667e92a0 100644 --- a/tests/manual/qnetworkreply/main.cpp +++ b/tests/manual/qnetworkreply/main.cpp @@ -47,6 +47,8 @@ #include <QtNetwork/qnetworkrequest.h> #include <QtNetwork/qnetworkaccessmanager.h> #include <QtNetwork/qsslconfiguration.h> +#include <QtNetwork/qhttpmultipart.h> +#include <QtCore/QJsonDocument> #include "../../auto/network-settings.h" #if defined(QT_BUILD_INTERNAL) && !defined(QT_NO_SSL) @@ -65,6 +67,9 @@ private slots: void limiting(); void setSslConfiguration_data(); void setSslConfiguration(); + void uploadToFacebook(); +private: + QHttpMultiPart *createFacebookMultiPart(const QByteArray &accessToken); }; QNetworkReply *reply; @@ -177,6 +182,108 @@ void tst_qnetworkreply::setSslConfiguration() #endif // QT_NO_SSL } +QHttpMultiPart *tst_qnetworkreply::createFacebookMultiPart(const QByteArray &accessToken) +{ + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpPart accessTokenPart; + accessTokenPart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"access_token\"")); + accessTokenPart.setBody(accessToken); + multiPart->append(accessTokenPart); + + QHttpPart batchPart; + batchPart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"batch\"")); + batchPart.setBody("[" +" {" +" \"attached_files\" : \"image1\"," +" \"body\" : \"message=&published=0\"," +" \"method\" : \"POST\"," +" \"relative_url\" : \"me/photos\"" +" }," +" {" +" \"attached_files\" : \"image2\"," +" \"body\" : \"message=&published=0\"," +" \"method\" : \"POST\"," +" \"relative_url\" : \"me/photos\"" +" }," +" {" +" \"attached_files\" : \"image3\"," +" \"body\" : \"message=&published=0\"," +" \"method\" : \"POST\"," +" \"relative_url\" : \"me/photos\"" +" }" +"]"); + multiPart->append(batchPart); + + QHttpPart imagePart1; + imagePart1.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpg")); + imagePart1.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image1\"; filename=\"image1.jpg\"")); + QFile *file1 = new QFile(QFINDTESTDATA("../../auto/network/access/qnetworkreply/image1.jpg")); + file1->open(QIODevice::ReadOnly); + imagePart1.setBodyDevice(file1); + file1->setParent(multiPart); + + multiPart->append(imagePart1); + + QHttpPart imagePart2; + imagePart2.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpg")); + imagePart2.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image2\"; filename=\"image2.jpg\"")); + QFile *file2 = new QFile(QFINDTESTDATA("../../auto/network/access/qnetworkreply/image2.jpg")); + file2->open(QIODevice::ReadOnly); + imagePart2.setBodyDevice(file2); + file2->setParent(multiPart); + + multiPart->append(imagePart2); + + QHttpPart imagePart3; + imagePart3.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpg")); + imagePart3.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image3\"; filename=\"image3.jpg\"")); + QFile *file3 = new QFile(QFINDTESTDATA("../../auto/network/access/qnetworkreply/image3.jpg")); + file3->open(QIODevice::ReadOnly); + imagePart3.setBodyDevice(file3); + file3->setParent(multiPart); + + multiPart->append(imagePart3); + return multiPart; +} + +void tst_qnetworkreply::uploadToFacebook() +{ + QByteArray accessToken = qgetenv("QT_FACEBOOK_ACCESS_TOKEN"); + if (accessToken.isEmpty()) + QSKIP("This test requires the QT_FACEBOOK_ACCESS_TOKEN environment variable to be set. " + "Do something like 'export QT_FACEBOOK_ACCESS_TOKEN=MyAccessToken'"); + + QElapsedTimer timer; + QNetworkAccessManager manager; + QNetworkRequest request(QUrl("https://graph.facebook.com/me/photos")); + QHttpMultiPart *multiPart = createFacebookMultiPart(accessToken); + timer.start(); + + QNetworkReply *reply = manager.post(request, multiPart); + multiPart->setParent(reply); + QObject::connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(120); + qint64 elapsed = timer.elapsed(); + QVERIFY(!QTestEventLoop::instance().timeout()); + qDebug() << "reply finished after" << elapsed / 1000.0 << "seconds"; + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QByteArray content = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(content); + QVERIFY(jsonDocument.isArray()); + QJsonArray uploadStatuses = jsonDocument.array(); + QVERIFY(uploadStatuses.size() > 0); + for (int a = 0; a < uploadStatuses.size(); a++) { + QJsonValue currentUploadStatus = uploadStatuses.at(a); + QVERIFY(currentUploadStatus.isObject()); + QJsonObject statusObject = currentUploadStatus.toObject(); + QJsonValue statusCode = statusObject.value(QLatin1String("code")); + QCOMPARE(statusCode.toVariant().toInt(), 200); // 200 OK + } +} + QTEST_MAIN(tst_qnetworkreply) #include "main.moc" |