blob: 2f8f933c9dfa2cca91ad731576d01e1de0760cc3 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
** 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 <QtTest/QtTest>
#include <QtTest/qtestcase.h>
#include <QtEndian>
#include <QDebug>
#include "QtWebSockets/qwebsocketprotocol.h"
#include "private/qwebsocketprotocol_p.h"
QT_USE_NAMESPACE
Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode)
Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
class tst_WebSocketProtocol : public QObject
{
Q_OBJECT
public:
tst_WebSocketProtocol();
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
void tst_validMasks_data();
void tst_validMasks();
void tst_opCodes_data();
void tst_opCodes();
void tst_closeCodes_data();
void tst_closeCodes();
void tst_versionFromString_data();
void tst_versionFromString();
};
tst_WebSocketProtocol::tst_WebSocketProtocol()
{}
void tst_WebSocketProtocol::initTestCase()
{
}
void tst_WebSocketProtocol::cleanupTestCase()
{}
void tst_WebSocketProtocol::init()
{
qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
}
void tst_WebSocketProtocol::cleanup()
{
}
void tst_WebSocketProtocol::tst_validMasks_data()
{
QTest::addColumn<quint32>("mask");
QTest::addColumn<QString>("inputdata");
QTest::addColumn<QByteArray>("result");
QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
QTest::newRow("ASCII payload of 8 characters")
<< 0x12345678u
<< QStringLiteral("abcdefgh")
<< QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
QTest::newRow("ASCII payload of 9 characters")
<< 0x12345678u
<< QStringLiteral("abcdefghi")
<< QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
//MSVC doesn't like UTF-8 in source code;
//the following text is represented in the string below: ∫∂ƒ©øØ
QTest::newRow("UTF-8 payload")
<< 0x12345678u
<< QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
<< QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
}
void tst_WebSocketProtocol::tst_validMasks()
{
QFETCH(quint32, mask);
QFETCH(QString, inputdata);
QFETCH(QByteArray, result);
//put latin1 into an explicit array
//otherwise, the intermediate object is deleted and the data pointer becomes invalid
QByteArray latin1 = inputdata.toLatin1();
char *data = latin1.data();
QWebSocketProtocol::mask(data, inputdata.size(), mask);
QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
}
void tst_WebSocketProtocol::tst_opCodes_data()
{
QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
QTest::addColumn<bool>("isReserved");
QTest::newRow("OpCodeBinary") << QWebSocketProtocol::OpCodeBinary << false;
QTest::newRow("OpCodeClose") << QWebSocketProtocol::OpCodeClose << false;
QTest::newRow("OpCodeContinue") << QWebSocketProtocol::OpCodeContinue << false;
QTest::newRow("OpCodePing") << QWebSocketProtocol::OpCodePing << false;
QTest::newRow("OpCodePong") << QWebSocketProtocol::OpCodePong << false;
QTest::newRow("OpCodeReserved3") << QWebSocketProtocol::OpCodeReserved3 << true;
QTest::newRow("OpCodeReserved4") << QWebSocketProtocol::OpCodeReserved4 << true;
QTest::newRow("OpCodeReserved5") << QWebSocketProtocol::OpCodeReserved5 << true;
QTest::newRow("OpCodeReserved6") << QWebSocketProtocol::OpCodeReserved6 << true;
QTest::newRow("OpCodeReserved7") << QWebSocketProtocol::OpCodeReserved7 << true;
QTest::newRow("OpCodeReserved8") << QWebSocketProtocol::OpCodeReservedB << true;
QTest::newRow("OpCodeReservedC") << QWebSocketProtocol::OpCodeReservedC << true;
QTest::newRow("OpCodeReservedD") << QWebSocketProtocol::OpCodeReservedD << true;
QTest::newRow("OpCodeReservedE") << QWebSocketProtocol::OpCodeReservedE << true;
QTest::newRow("OpCodeReservedF") << QWebSocketProtocol::OpCodeReservedF << true;
QTest::newRow("OpCodeText") << QWebSocketProtocol::OpCodeText << false;
}
void tst_WebSocketProtocol::tst_opCodes()
{
QFETCH(QWebSocketProtocol::OpCode, opCode);
QFETCH(bool, isReserved);
bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
QCOMPARE(result, isReserved);
}
void tst_WebSocketProtocol::tst_closeCodes_data()
{
QTest::addColumn<int>("closeCode");
QTest::addColumn<bool>("isValid");
for (int i = 0; i < 1000; ++i)
{
QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
}
for (int i = 1000; i < 1004; ++i)
{
QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
}
QTest::newRow("Close code 1004") << 1004 << false;
QTest::newRow("Close code 1005") << 1005 << false;
QTest::newRow("Close code 1006") << 1006 << false;
for (int i = 1007; i < 1012; ++i)
{
QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
}
for (int i = 1013; i < 3000; ++i)
{
QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
}
for (int i = 3000; i < 5000; ++i)
{
QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
}
QTest::newRow("Close code 5000") << 1004 << false;
QTest::newRow("Close code 6000") << 1004 << false;
QTest::newRow("Close code 7000") << 1004 << false;
}
void tst_WebSocketProtocol::tst_closeCodes()
{
QFETCH(int, closeCode);
QFETCH(bool, isValid);
bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
QCOMPARE(result, isValid);
}
void tst_WebSocketProtocol::tst_versionFromString_data()
{
QTest::addColumn<QWebSocketProtocol::Version>("version");
QTest::addColumn<QString>("versionString");
//happy flow; good data
QTest::newRow("Version 0")
<< QWebSocketProtocol::Version0
<< QStringLiteral("0");
QTest::newRow("Version 4")
<< QWebSocketProtocol::Version4
<< QStringLiteral("4");
QTest::newRow("Version 5")
<< QWebSocketProtocol::Version5
<< QStringLiteral("5");
QTest::newRow("Version 6")
<< QWebSocketProtocol::Version6
<< QStringLiteral("6");
QTest::newRow("Version 7")
<< QWebSocketProtocol::Version7
<< QStringLiteral("7");
QTest::newRow("Version 8")
<< QWebSocketProtocol::Version8
<< QStringLiteral("8");
QTest::newRow("Version 13")
<< QWebSocketProtocol::Version13
<< QStringLiteral("13");
//rainy flow; invalid data
QTest::newRow("Version -1")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("-1");
QTest::newRow("Version 1")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("1");
QTest::newRow("Version 2")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("2");
QTest::newRow("Version 3")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("3");
QTest::newRow("Version 9")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("9");
QTest::newRow("Version 10")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("10");
QTest::newRow("Version 11")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("11");
QTest::newRow("Version 12")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("12");
QTest::newRow("Version abcd")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("abcd");
QTest::newRow("Version 1.6")
<< QWebSocketProtocol::VersionUnknown
<< QStringLiteral("1.6");
QTest::newRow("Version empty")
<< QWebSocketProtocol::VersionUnknown
<< QString();
}
void tst_WebSocketProtocol::tst_versionFromString()
{
QFETCH(QWebSocketProtocol::Version, version);
QFETCH(QString, versionString);
QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
}
QTEST_MAIN(tst_WebSocketProtocol)
#include "tst_websocketprotocol.moc"