3ba9fe85e9cbe90e5a6d762101b516421a3dd307
[contrib/qtwebsockets.git] / tests / auto / websocketprotocol / tst_websocketprotocol.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Kurt Pattyn <pattyn.kurt@gmail.com>.
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <QtTest/qtestcase.h>
43 #include <QtEndian>
44
45 #include <QDebug>
46
47 #include "QtWebSockets/qwebsocketprotocol.h"
48 #include "private/qwebsocketprotocol_p.h"
49
50 QT_USE_NAMESPACE
51
52 Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
53 Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode)
54 Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
55
56 class tst_WebSocketProtocol : public QObject
57 {
58     Q_OBJECT
59
60 public:
61     tst_WebSocketProtocol();
62
63 private Q_SLOTS:
64     void initTestCase();
65     void cleanupTestCase();
66     void init();
67     void cleanup();
68
69     void tst_validMasks_data();
70     void tst_validMasks();
71
72     void tst_opCodes_data();
73     void tst_opCodes();
74
75     void tst_closeCodes_data();
76     void tst_closeCodes();
77
78     void tst_versionFromString_data();
79     void tst_versionFromString();
80 };
81
82 tst_WebSocketProtocol::tst_WebSocketProtocol()
83 {}
84
85 void tst_WebSocketProtocol::initTestCase()
86 {
87 }
88
89 void tst_WebSocketProtocol::cleanupTestCase()
90 {}
91
92 void tst_WebSocketProtocol::init()
93 {
94     qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
95     qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
96 }
97
98 void tst_WebSocketProtocol::cleanup()
99 {
100 }
101
102 void tst_WebSocketProtocol::tst_validMasks_data()
103 {
104     QTest::addColumn<quint32>("mask");
105     QTest::addColumn<QString>("inputdata");
106     QTest::addColumn<QByteArray>("result");
107
108     QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
109     QTest::newRow("ASCII payload of 8 characters")
110             << 0x12345678u
111             << QStringLiteral("abcdefgh")
112             << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
113     QTest::newRow("ASCII payload of 9 characters")
114             << 0x12345678u
115             << QStringLiteral("abcdefghi")
116             << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
117     //MSVC doesn't like UTF-8 in source code;
118     //the following text is represented in the string below: ∫∂ƒ©øØ
119     QTest::newRow("UTF-8 payload")
120             << 0x12345678u
121             << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
122             << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
123 }
124
125 void tst_WebSocketProtocol::tst_validMasks()
126 {
127     QFETCH(quint32, mask);
128     QFETCH(QString, inputdata);
129     QFETCH(QByteArray, result);
130
131     //put latin1 into an explicit array
132     //otherwise, the intermediate object is deleted and the data pointer becomes invalid
133     QByteArray latin1 = inputdata.toLatin1();
134     char *data = latin1.data();
135
136     QWebSocketProtocol::mask(data, inputdata.size(), mask);
137     QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
138 }
139
140 void tst_WebSocketProtocol::tst_opCodes_data()
141 {
142     QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
143     QTest::addColumn<bool>("isReserved");
144
145     QTest::newRow("OpCodeBinary")       << QWebSocketProtocol::OpCodeBinary << false;
146     QTest::newRow("OpCodeClose")        << QWebSocketProtocol::OpCodeClose << false;
147     QTest::newRow("OpCodeContinue")     << QWebSocketProtocol::OpCodeContinue << false;
148     QTest::newRow("OpCodePing")         << QWebSocketProtocol::OpCodePing << false;
149     QTest::newRow("OpCodePong")         << QWebSocketProtocol::OpCodePong << false;
150     QTest::newRow("OpCodeReserved3")    << QWebSocketProtocol::OpCodeReserved3 << true;
151     QTest::newRow("OpCodeReserved4")    << QWebSocketProtocol::OpCodeReserved4 << true;
152     QTest::newRow("OpCodeReserved5")    << QWebSocketProtocol::OpCodeReserved5 << true;
153     QTest::newRow("OpCodeReserved6")    << QWebSocketProtocol::OpCodeReserved6 << true;
154     QTest::newRow("OpCodeReserved7")    << QWebSocketProtocol::OpCodeReserved7 << true;
155     QTest::newRow("OpCodeReserved8")    << QWebSocketProtocol::OpCodeReservedB << true;
156     QTest::newRow("OpCodeReservedC")    << QWebSocketProtocol::OpCodeReservedC << true;
157     QTest::newRow("OpCodeReservedD")    << QWebSocketProtocol::OpCodeReservedD << true;
158     QTest::newRow("OpCodeReservedE")    << QWebSocketProtocol::OpCodeReservedE << true;
159     QTest::newRow("OpCodeReservedF")    << QWebSocketProtocol::OpCodeReservedF << true;
160     QTest::newRow("OpCodeText")         << QWebSocketProtocol::OpCodeText << false;
161 }
162
163 void tst_WebSocketProtocol::tst_opCodes()
164 {
165     QFETCH(QWebSocketProtocol::OpCode, opCode);
166     QFETCH(bool, isReserved);
167
168     bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
169
170     QCOMPARE(result, isReserved);
171 }
172
173 void tst_WebSocketProtocol::tst_closeCodes_data()
174 {
175     QTest::addColumn<int>("closeCode");
176     QTest::addColumn<bool>("isValid");
177
178     for (int i = 0; i < 1000; ++i)
179     {
180         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
181     }
182
183     for (int i = 1000; i < 1004; ++i)
184     {
185         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
186     }
187
188     QTest::newRow("Close code 1004") << 1004 << false;
189     QTest::newRow("Close code 1005") << 1005 << false;
190     QTest::newRow("Close code 1006") << 1006 << false;
191
192     for (int i = 1007; i < 1012; ++i)
193     {
194         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
195     }
196
197     for (int i = 1013; i < 3000; ++i)
198     {
199         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
200     }
201
202     for (int i = 3000; i < 5000; ++i)
203     {
204         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
205     }
206
207     QTest::newRow("Close code 5000") << 1004 << false;
208     QTest::newRow("Close code 6000") << 1004 << false;
209     QTest::newRow("Close code 7000") << 1004 << false;
210 }
211
212 void tst_WebSocketProtocol::tst_closeCodes()
213 {
214     QFETCH(int, closeCode);
215     QFETCH(bool, isValid);
216
217     bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
218
219     QCOMPARE(result, isValid);
220 }
221
222 void tst_WebSocketProtocol::tst_versionFromString_data()
223 {
224     QTest::addColumn<QWebSocketProtocol::Version>("version");
225     QTest::addColumn<QString>("versionString");
226
227     //happy flow; good data
228     QTest::newRow("Version 0")
229             << QWebSocketProtocol::Version0
230             << QStringLiteral("0");
231     QTest::newRow("Version 4")
232             << QWebSocketProtocol::Version4
233             << QStringLiteral("4");
234     QTest::newRow("Version 5")
235             << QWebSocketProtocol::Version5
236             << QStringLiteral("5");
237     QTest::newRow("Version 6")
238             << QWebSocketProtocol::Version6
239             << QStringLiteral("6");
240     QTest::newRow("Version 7")
241             << QWebSocketProtocol::Version7
242             << QStringLiteral("7");
243     QTest::newRow("Version 8")
244             << QWebSocketProtocol::Version8
245             << QStringLiteral("8");
246     QTest::newRow("Version 13")
247             << QWebSocketProtocol::Version13
248             << QStringLiteral("13");
249
250     //rainy flow; invalid data
251     QTest::newRow("Version -1")
252             << QWebSocketProtocol::VersionUnknown
253             << QStringLiteral("-1");
254     QTest::newRow("Version 1")
255             << QWebSocketProtocol::VersionUnknown
256             << QStringLiteral("1");
257     QTest::newRow("Version 2")
258             << QWebSocketProtocol::VersionUnknown
259             << QStringLiteral("2");
260     QTest::newRow("Version 3")
261             << QWebSocketProtocol::VersionUnknown
262             << QStringLiteral("3");
263     QTest::newRow("Version 9")
264             << QWebSocketProtocol::VersionUnknown
265             << QStringLiteral("9");
266     QTest::newRow("Version 10")
267             << QWebSocketProtocol::VersionUnknown
268             << QStringLiteral("10");
269     QTest::newRow("Version 11")
270             << QWebSocketProtocol::VersionUnknown
271             << QStringLiteral("11");
272     QTest::newRow("Version 12")
273             << QWebSocketProtocol::VersionUnknown
274             << QStringLiteral("12");
275     QTest::newRow("Version abcd")
276             << QWebSocketProtocol::VersionUnknown
277             << QStringLiteral("abcd");
278     QTest::newRow("Version 1.6")
279             << QWebSocketProtocol::VersionUnknown
280             << QStringLiteral("1.6");
281     QTest::newRow("Version empty")
282             << QWebSocketProtocol::VersionUnknown
283             << QString();
284 }
285
286 void tst_WebSocketProtocol::tst_versionFromString()
287 {
288     QFETCH(QWebSocketProtocol::Version, version);
289     QFETCH(QString, versionString);
290
291     QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
292 }
293
294 QTEST_MAIN(tst_WebSocketProtocol)
295
296 #include "tst_websocketprotocol.moc"
297