b8948d553d631db6ab257f0df867b915dc1fbc16
[contrib/qtwebsockets.git] / tests / auto / websocketprotocol / tst_websocketprotocol.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
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
55 class tst_WebSocketProtocol : public QObject
56 {
57     Q_OBJECT
58
59 public:
60     tst_WebSocketProtocol();
61
62 private Q_SLOTS:
63     void initTestCase();
64     void cleanupTestCase();
65     void init();
66     void cleanup();
67
68     void tst_validMasks_data();
69     void tst_validMasks();
70
71     void tst_opCodes_data();
72     void tst_opCodes();
73
74     void tst_closeCodes_data();
75     void tst_closeCodes();
76
77     void tst_versionFromString_data();
78     void tst_versionFromString();
79 };
80
81 tst_WebSocketProtocol::tst_WebSocketProtocol()
82 {}
83
84 void tst_WebSocketProtocol::initTestCase()
85 {
86 }
87
88 void tst_WebSocketProtocol::cleanupTestCase()
89 {}
90
91 void tst_WebSocketProtocol::init()
92 {
93     qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
94     qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
95 }
96
97 void tst_WebSocketProtocol::cleanup()
98 {
99 }
100
101 void tst_WebSocketProtocol::tst_validMasks_data()
102 {
103     QTest::addColumn<quint32>("mask");
104     QTest::addColumn<QString>("inputdata");
105     QTest::addColumn<QByteArray>("result");
106
107     QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
108     QTest::newRow("ASCII payload of 8 characters")
109             << 0x12345678u
110             << QStringLiteral("abcdefgh")
111             << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
112     QTest::newRow("ASCII payload of 9 characters")
113             << 0x12345678u
114             << QStringLiteral("abcdefghi")
115             << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
116     //MSVC doesn't like UTF-8 in source code;
117     //the following text is represented in the string below: ∫∂ƒ©øØ
118     QTest::newRow("UTF-8 payload")
119             << 0x12345678u
120             << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
121             << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
122 }
123
124 void tst_WebSocketProtocol::tst_validMasks()
125 {
126     QFETCH(quint32, mask);
127     QFETCH(QString, inputdata);
128     QFETCH(QByteArray, result);
129
130     //put latin1 into an explicit array
131     //otherwise, the intermediate object is deleted and the data pointer becomes invalid
132     QByteArray latin1 = inputdata.toLatin1();
133     char *data = latin1.data();
134
135     QWebSocketProtocol::mask(data, inputdata.size(), mask);
136     QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
137 }
138
139 void tst_WebSocketProtocol::tst_opCodes_data()
140 {
141     QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
142     QTest::addColumn<bool>("isReserved");
143
144     QTest::newRow("OpCodeBinary")       << QWebSocketProtocol::OpCodeBinary << false;
145     QTest::newRow("OpCodeClose")        << QWebSocketProtocol::OpCodeClose << false;
146     QTest::newRow("OpCodeContinue")     << QWebSocketProtocol::OpCodeContinue << false;
147     QTest::newRow("OpCodePing")         << QWebSocketProtocol::OpCodePing << false;
148     QTest::newRow("OpCodePong")         << QWebSocketProtocol::OpCodePong << false;
149     QTest::newRow("OpCodeReserved3")    << QWebSocketProtocol::OpCodeReserved3 << true;
150     QTest::newRow("OpCodeReserved4")    << QWebSocketProtocol::OpCodeReserved4 << true;
151     QTest::newRow("OpCodeReserved5")    << QWebSocketProtocol::OpCodeReserved5 << true;
152     QTest::newRow("OpCodeReserved6")    << QWebSocketProtocol::OpCodeReserved6 << true;
153     QTest::newRow("OpCodeReserved7")    << QWebSocketProtocol::OpCodeReserved7 << true;
154     QTest::newRow("OpCodeReserved8")    << QWebSocketProtocol::OpCodeReservedB << true;
155     QTest::newRow("OpCodeReservedC")    << QWebSocketProtocol::OpCodeReservedC << true;
156     QTest::newRow("OpCodeReservedD")    << QWebSocketProtocol::OpCodeReservedD << true;
157     QTest::newRow("OpCodeReservedE")    << QWebSocketProtocol::OpCodeReservedE << true;
158     QTest::newRow("OpCodeReservedF")    << QWebSocketProtocol::OpCodeReservedF << true;
159     QTest::newRow("OpCodeText")         << QWebSocketProtocol::OpCodeText << false;
160 }
161
162 void tst_WebSocketProtocol::tst_opCodes()
163 {
164     QFETCH(QWebSocketProtocol::OpCode, opCode);
165     QFETCH(bool, isReserved);
166
167     bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
168
169     QCOMPARE(result, isReserved);
170 }
171
172 void tst_WebSocketProtocol::tst_closeCodes_data()
173 {
174     QTest::addColumn<int>("closeCode");
175     QTest::addColumn<bool>("isValid");
176
177     for (int i = 0; i < 1000; ++i)
178     {
179         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
180     }
181
182     for (int i = 1000; i < 1004; ++i)
183     {
184         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
185     }
186
187     QTest::newRow("Close code 1004") << 1004 << false;
188     QTest::newRow("Close code 1005") << 1005 << false;
189     QTest::newRow("Close code 1006") << 1006 << false;
190
191     for (int i = 1007; i < 1012; ++i)
192     {
193         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
194     }
195
196     for (int i = 1013; i < 3000; ++i)
197     {
198         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
199     }
200
201     for (int i = 3000; i < 5000; ++i)
202     {
203         QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
204     }
205
206     QTest::newRow("Close code 5000") << 1004 << false;
207     QTest::newRow("Close code 6000") << 1004 << false;
208     QTest::newRow("Close code 7000") << 1004 << false;
209 }
210
211 void tst_WebSocketProtocol::tst_closeCodes()
212 {
213     QFETCH(int, closeCode);
214     QFETCH(bool, isValid);
215
216     bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
217
218     QCOMPARE(result, isValid);
219 }
220
221 void tst_WebSocketProtocol::tst_versionFromString_data()
222 {
223     QTest::addColumn<QWebSocketProtocol::Version>("version");
224     QTest::addColumn<QString>("versionString");
225
226     //happy flow; good data
227     QTest::newRow("Version 0")
228             << QWebSocketProtocol::Version0
229             << QStringLiteral("0");
230     QTest::newRow("Version 4")
231             << QWebSocketProtocol::Version4
232             << QStringLiteral("4");
233     QTest::newRow("Version 5")
234             << QWebSocketProtocol::Version5
235             << QStringLiteral("5");
236     QTest::newRow("Version 6")
237             << QWebSocketProtocol::Version6
238             << QStringLiteral("6");
239     QTest::newRow("Version 7")
240             << QWebSocketProtocol::Version7
241             << QStringLiteral("7");
242     QTest::newRow("Version 8")
243             << QWebSocketProtocol::Version8
244             << QStringLiteral("8");
245     QTest::newRow("Version 13")
246             << QWebSocketProtocol::Version13
247             << QStringLiteral("13");
248
249     //rainy flow; invalid data
250     QTest::newRow("Version -1")
251             << QWebSocketProtocol::VersionUnknown
252             << QStringLiteral("-1");
253     QTest::newRow("Version 1")
254             << QWebSocketProtocol::VersionUnknown
255             << QStringLiteral("1");
256     QTest::newRow("Version 2")
257             << QWebSocketProtocol::VersionUnknown
258             << QStringLiteral("2");
259     QTest::newRow("Version 3")
260             << QWebSocketProtocol::VersionUnknown
261             << QStringLiteral("3");
262     QTest::newRow("Version 9")
263             << QWebSocketProtocol::VersionUnknown
264             << QStringLiteral("9");
265     QTest::newRow("Version 10")
266             << QWebSocketProtocol::VersionUnknown
267             << QStringLiteral("10");
268     QTest::newRow("Version 11")
269             << QWebSocketProtocol::VersionUnknown
270             << QStringLiteral("11");
271     QTest::newRow("Version 12")
272             << QWebSocketProtocol::VersionUnknown
273             << QStringLiteral("12");
274     QTest::newRow("Version abcd")
275             << QWebSocketProtocol::VersionUnknown
276             << QStringLiteral("abcd");
277     QTest::newRow("Version 1.6")
278             << QWebSocketProtocol::VersionUnknown
279             << QStringLiteral("1.6");
280     QTest::newRow("Version empty")
281             << QWebSocketProtocol::VersionUnknown
282             << QString();
283 }
284
285 void tst_WebSocketProtocol::tst_versionFromString()
286 {
287     QFETCH(QWebSocketProtocol::Version, version);
288     QFETCH(QString, versionString);
289
290     QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
291 }
292
293 QTEST_MAIN(tst_WebSocketProtocol)
294
295 #include "tst_websocketprotocol.moc"
296