Compile fix without proxy support
[contrib/qtwebsockets.git] / tests / auto / qwebsocket / tst_qwebsocket.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 <QString>
42 #include <QtTest>
43 #include <QtWebSockets/QWebSocket>
44 #include <QtWebSockets/QWebSocketServer>
45 #include <QtWebSockets/qwebsocketprotocol.h>
46
47 QT_USE_NAMESPACE
48
49 Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
50
51 class EchoServer : public QObject
52 {
53     Q_OBJECT
54 public:
55     explicit EchoServer(QObject *parent = Q_NULLPTR);
56     ~EchoServer();
57
58     QHostAddress hostAddress() const { return m_pWebSocketServer->serverAddress(); }
59     quint16 port() const { return m_pWebSocketServer->serverPort(); }
60
61 Q_SIGNALS:
62     void closed();
63
64 private Q_SLOTS:
65     void onNewConnection();
66     void processTextMessage(QString message);
67     void processBinaryMessage(QByteArray message);
68     void socketDisconnected();
69
70 private:
71     QWebSocketServer *m_pWebSocketServer;
72     QList<QWebSocket *> m_clients;
73 };
74
75 EchoServer::EchoServer(QObject *parent) :
76     QObject(parent),
77     m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Echo Server"),
78                                             QWebSocketServer::NonSecureMode, this)),
79     m_clients()
80 {
81     if (m_pWebSocketServer->listen()) {
82         connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
83                 this, &EchoServer::onNewConnection);
84         connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &EchoServer::closed);
85     }
86 }
87
88 EchoServer::~EchoServer()
89 {
90     m_pWebSocketServer->close();
91     qDeleteAll(m_clients.begin(), m_clients.end());
92 }
93
94 void EchoServer::onNewConnection()
95 {
96     QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
97
98     connect(pSocket, &QWebSocket::textMessageReceived, this, &EchoServer::processTextMessage);
99     connect(pSocket, &QWebSocket::binaryMessageReceived, this, &EchoServer::processBinaryMessage);
100     connect(pSocket, &QWebSocket::disconnected, this, &EchoServer::socketDisconnected);
101
102     m_clients << pSocket;
103 }
104
105 void EchoServer::processTextMessage(QString message)
106 {
107     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
108     if (pClient) {
109         pClient->sendTextMessage(message);
110     }
111 }
112
113 void EchoServer::processBinaryMessage(QByteArray message)
114 {
115     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
116     if (pClient) {
117         pClient->sendBinaryMessage(message);
118     }
119 }
120
121 void EchoServer::socketDisconnected()
122 {
123     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
124     if (pClient) {
125         m_clients.removeAll(pClient);
126         pClient->deleteLater();
127     }
128 }
129
130 class tst_QWebSocket : public QObject
131 {
132     Q_OBJECT
133
134 public:
135     tst_QWebSocket();
136
137 private Q_SLOTS:
138     void init();
139     void initTestCase();
140     void cleanupTestCase();
141     void tst_initialisation_data();
142     void tst_initialisation();
143     void tst_settersAndGetters();
144     void tst_invalidOpen_data();
145     void tst_invalidOpen();
146     void tst_invalidOrigin();
147     void tst_sendTextMessage();
148     void tst_sendBinaryMessage();
149     void tst_errorString();
150 #ifndef QT_NO_NETWORKPROXY
151     void tst_setProxy();
152 #endif
153 };
154
155 tst_QWebSocket::tst_QWebSocket()
156 {
157 }
158
159 void tst_QWebSocket::init()
160 {
161     qRegisterMetaType<QWebSocketProtocol::Version>("QWebSocketProtocol::Version");
162 }
163
164 void tst_QWebSocket::initTestCase()
165 {
166 }
167
168 void tst_QWebSocket::cleanupTestCase()
169 {
170 }
171
172 void tst_QWebSocket::tst_initialisation_data()
173 {
174     QTest::addColumn<QString>("origin");
175     QTest::addColumn<QString>("expectedOrigin");
176     QTest::addColumn<QWebSocketProtocol::Version>("version");
177     QTest::addColumn<QWebSocketProtocol::Version>("expectedVersion");
178
179     QTest::newRow("Default origin and version")
180             << QString() << QString()
181             << QWebSocketProtocol::VersionUnknown << QWebSocketProtocol::VersionLatest;
182     QTest::newRow("Specific origin and default version")
183             << QStringLiteral("qt-project.org") << QStringLiteral("qt-project.org")
184             << QWebSocketProtocol::VersionUnknown << QWebSocketProtocol::VersionLatest;
185     QTest::newRow("Specific origin and specific version")
186             << QStringLiteral("qt-project.org") << QStringLiteral("qt-project.org")
187             << QWebSocketProtocol::Version7 << QWebSocketProtocol::Version7;
188 }
189
190 void tst_QWebSocket::tst_initialisation()
191 {
192     QFETCH(QString, origin);
193     QFETCH(QString, expectedOrigin);
194     QFETCH(QWebSocketProtocol::Version, version);
195     QFETCH(QWebSocketProtocol::Version, expectedVersion);
196
197     QScopedPointer<QWebSocket> socket;
198
199     if (origin.isEmpty() && (version == QWebSocketProtocol::VersionUnknown))
200         socket.reset(new QWebSocket);
201     else if (!origin.isEmpty() && (version == QWebSocketProtocol::VersionUnknown))
202         socket.reset(new QWebSocket(origin));
203     else
204         socket.reset(new QWebSocket(origin, version));
205
206     QCOMPARE(socket->origin(), expectedOrigin);
207     QCOMPARE(socket->version(), expectedVersion);
208     QCOMPARE(socket->error(), QAbstractSocket::UnknownSocketError);
209     QVERIFY(socket->errorString().isEmpty());
210     QVERIFY(!socket->isValid());
211     QVERIFY(socket->localAddress().isNull());
212     QCOMPARE(socket->localPort(), quint16(0));
213     QCOMPARE(socket->pauseMode(), QAbstractSocket::PauseNever);
214     QVERIFY(socket->peerAddress().isNull());
215     QCOMPARE(socket->peerPort(), quint16(0));
216     QVERIFY(socket->peerName().isEmpty());
217     QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
218     QCOMPARE(socket->readBufferSize(), 0);
219     QVERIFY(socket->resourceName().isEmpty());
220     QVERIFY(!socket->requestUrl().isValid());
221     QCOMPARE(socket->closeCode(), QWebSocketProtocol::CloseCodeNormal);
222     QVERIFY(socket->closeReason().isEmpty());
223     QVERIFY(socket->flush());
224     QCOMPARE(socket->sendTextMessage(QStringLiteral("A text message")), 0);
225     QCOMPARE(socket->sendBinaryMessage(QByteArrayLiteral("A binary message")), 0);
226 }
227
228 void tst_QWebSocket::tst_settersAndGetters()
229 {
230     QWebSocket socket;
231
232     socket.setPauseMode(QAbstractSocket::PauseNever);
233     QCOMPARE(socket.pauseMode(), QAbstractSocket::PauseNever);
234     socket.setPauseMode(QAbstractSocket::PauseOnSslErrors);
235     QCOMPARE(socket.pauseMode(), QAbstractSocket::PauseOnSslErrors);
236
237     socket.setReadBufferSize(0);
238     QCOMPARE(socket.readBufferSize(), 0);
239     socket.setReadBufferSize(128);
240     QCOMPARE(socket.readBufferSize(), 128);
241     socket.setReadBufferSize(-1);
242     QCOMPARE(socket.readBufferSize(), -1);
243 }
244
245 void tst_QWebSocket::tst_invalidOpen_data()
246 {
247     QTest::addColumn<QString>("url");
248     QTest::addColumn<QString>("expectedUrl");
249     QTest::addColumn<QString>("expectedPeerName");
250     QTest::addColumn<QString>("expectedResourceName");
251     QTest::addColumn<QAbstractSocket::SocketState>("stateAfterOpenCall");
252     QTest::addColumn<int>("disconnectedCount");
253     QTest::addColumn<int>("stateChangedCount");
254
255     QTest::newRow("Illegal local address")
256             << QStringLiteral("ws://127.0.0.1:1/") << QStringLiteral("ws://127.0.0.1:1/")
257             << QStringLiteral("127.0.0.1")
258             << QStringLiteral("/") << QAbstractSocket::ConnectingState
259             << 1
260             << 2;  //going from connecting to disconnected
261     QTest::newRow("URL containing new line in the hostname")
262             << QStringLiteral("ws://myhacky\r\nserver/") << QString()
263             << QString()
264             << QString() << QAbstractSocket::UnconnectedState
265             << 0 << 0;
266     QTest::newRow("URL containing new line in the resource name")
267             << QStringLiteral("ws://127.0.0.1:1/tricky\r\npath") << QString()
268             << QString()
269             << QString()
270             << QAbstractSocket::UnconnectedState
271             << 0 << 0;
272 }
273
274 void tst_QWebSocket::tst_invalidOpen()
275 {
276     QFETCH(QString, url);
277     QFETCH(QString, expectedUrl);
278     QFETCH(QString, expectedPeerName);
279     QFETCH(QString, expectedResourceName);
280     QFETCH(QAbstractSocket::SocketState, stateAfterOpenCall);
281     QFETCH(int, disconnectedCount);
282     QFETCH(int, stateChangedCount);
283     QWebSocket socket;
284     QSignalSpy errorSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
285     QSignalSpy aboutToCloseSpy(&socket, SIGNAL(aboutToClose()));
286     QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
287     QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
288     QSignalSpy stateChangedSpy(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
289     QSignalSpy readChannelFinishedSpy(&socket, SIGNAL(readChannelFinished()));
290     QSignalSpy textFrameReceivedSpy(&socket, SIGNAL(textFrameReceived(QString,bool)));
291     QSignalSpy binaryFrameReceivedSpy(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool)));
292     QSignalSpy textMessageReceivedSpy(&socket, SIGNAL(textMessageReceived(QString)));
293     QSignalSpy binaryMessageReceivedSpy(&socket, SIGNAL(binaryMessageReceived(QByteArray)));
294     QSignalSpy pongSpy(&socket, SIGNAL(pong(quint64,QByteArray)));
295     QSignalSpy bytesWrittenSpy(&socket, SIGNAL(bytesWritten(qint64)));
296
297     socket.open(QUrl(url));
298
299     QVERIFY(socket.origin().isEmpty());
300     QCOMPARE(socket.version(), QWebSocketProtocol::VersionLatest);
301     //at this point the socket is in a connecting state
302     //so, there should no error at this point
303     QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
304     QVERIFY(!socket.errorString().isEmpty());
305     QVERIFY(!socket.isValid());
306     QVERIFY(socket.localAddress().isNull());
307     QCOMPARE(socket.localPort(), quint16(0));
308     QCOMPARE(socket.pauseMode(), QAbstractSocket::PauseNever);
309     QVERIFY(socket.peerAddress().isNull());
310     QCOMPARE(socket.peerPort(), quint16(0));
311     QCOMPARE(socket.peerName(), expectedPeerName);
312     QCOMPARE(socket.state(), stateAfterOpenCall);
313     QCOMPARE(socket.readBufferSize(), 0);
314     QCOMPARE(socket.resourceName(), expectedResourceName);
315     QCOMPARE(socket.requestUrl().toString(), expectedUrl);
316     QCOMPARE(socket.closeCode(), QWebSocketProtocol::CloseCodeNormal);
317     QVERIFY(socket.closeReason().isEmpty());
318     QCOMPARE(socket.sendTextMessage(QStringLiteral("A text message")), 0);
319     QCOMPARE(socket.sendBinaryMessage(QByteArrayLiteral("A text message")), 0);
320
321     if (errorSpy.count() == 0)
322         QVERIFY(errorSpy.wait());
323     QCOMPARE(errorSpy.count(), 1);
324     QList<QVariant> arguments = errorSpy.takeFirst();
325     QAbstractSocket::SocketError socketError =
326             qvariant_cast<QAbstractSocket::SocketError>(arguments.at(0));
327     QCOMPARE(socketError, QAbstractSocket::ConnectionRefusedError);
328     QCOMPARE(aboutToCloseSpy.count(), 0);
329     QCOMPARE(connectedSpy.count(), 0);
330     QCOMPARE(disconnectedSpy.count(), disconnectedCount);
331     QCOMPARE(stateChangedSpy.count(), stateChangedCount);
332     if (stateChangedCount == 2) {
333         arguments = stateChangedSpy.takeFirst();
334         QAbstractSocket::SocketState socketState =
335                 qvariant_cast<QAbstractSocket::SocketState>(arguments.at(0));
336         arguments = stateChangedSpy.takeFirst();
337         socketState = qvariant_cast<QAbstractSocket::SocketState>(arguments.at(0));
338         QCOMPARE(socketState, QAbstractSocket::UnconnectedState);
339     }
340     QCOMPARE(readChannelFinishedSpy.count(), 0);
341     QCOMPARE(textFrameReceivedSpy.count(), 0);
342     QCOMPARE(binaryFrameReceivedSpy.count(), 0);
343     QCOMPARE(textMessageReceivedSpy.count(), 0);
344     QCOMPARE(binaryMessageReceivedSpy.count(), 0);
345     QCOMPARE(pongSpy.count(), 0);
346     QCOMPARE(bytesWrittenSpy.count(), 0);
347 }
348
349 void tst_QWebSocket::tst_invalidOrigin()
350 {
351     QWebSocket socket(QStringLiteral("My server\r\nin the wild."));
352
353     QSignalSpy errorSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
354     QSignalSpy aboutToCloseSpy(&socket, SIGNAL(aboutToClose()));
355     QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
356     QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
357     QSignalSpy stateChangedSpy(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
358     QSignalSpy readChannelFinishedSpy(&socket, SIGNAL(readChannelFinished()));
359     QSignalSpy textFrameReceivedSpy(&socket, SIGNAL(textFrameReceived(QString,bool)));
360     QSignalSpy binaryFrameReceivedSpy(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool)));
361     QSignalSpy textMessageReceivedSpy(&socket, SIGNAL(textMessageReceived(QString)));
362     QSignalSpy binaryMessageReceivedSpy(&socket, SIGNAL(binaryMessageReceived(QByteArray)));
363     QSignalSpy pongSpy(&socket, SIGNAL(pong(quint64,QByteArray)));
364     QSignalSpy bytesWrittenSpy(&socket, SIGNAL(bytesWritten(qint64)));
365
366     socket.open(QUrl(QStringLiteral("ws://127.0.0.1:1/")));
367
368     //at this point the socket is in a connecting state
369     //so, there should no error at this point
370     QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
371     QVERIFY(!socket.errorString().isEmpty());
372     QVERIFY(!socket.isValid());
373     QVERIFY(socket.localAddress().isNull());
374     QCOMPARE(socket.localPort(), quint16(0));
375     QCOMPARE(socket.pauseMode(), QAbstractSocket::PauseNever);
376     QVERIFY(socket.peerAddress().isNull());
377     QCOMPARE(socket.peerPort(), quint16(0));
378     QCOMPARE(socket.peerName(), QStringLiteral("127.0.0.1"));
379     QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
380     QCOMPARE(socket.readBufferSize(), 0);
381     QCOMPARE(socket.resourceName(), QStringLiteral("/"));
382     QCOMPARE(socket.requestUrl(), QUrl(QStringLiteral("ws://127.0.0.1:1/")));
383     QCOMPARE(socket.closeCode(), QWebSocketProtocol::CloseCodeNormal);
384
385     QVERIFY(errorSpy.wait());
386
387     QCOMPARE(errorSpy.count(), 1);
388     QList<QVariant> arguments = errorSpy.takeFirst();
389     QAbstractSocket::SocketError socketError =
390             qvariant_cast<QAbstractSocket::SocketError>(arguments.at(0));
391     QCOMPARE(socketError, QAbstractSocket::ConnectionRefusedError);
392     QCOMPARE(aboutToCloseSpy.count(), 0);
393     QCOMPARE(connectedSpy.count(), 0);
394     QCOMPARE(disconnectedSpy.count(), 1);
395     QCOMPARE(stateChangedSpy.count(), 2);   //connectingstate, unconnectedstate
396     arguments = stateChangedSpy.takeFirst();
397     QAbstractSocket::SocketState socketState =
398             qvariant_cast<QAbstractSocket::SocketState>(arguments.at(0));
399     arguments = stateChangedSpy.takeFirst();
400     socketState = qvariant_cast<QAbstractSocket::SocketState>(arguments.at(0));
401     QCOMPARE(socketState, QAbstractSocket::UnconnectedState);
402     QCOMPARE(readChannelFinishedSpy.count(), 0);
403     QCOMPARE(textFrameReceivedSpy.count(), 0);
404     QCOMPARE(binaryFrameReceivedSpy.count(), 0);
405     QCOMPARE(textMessageReceivedSpy.count(), 0);
406     QCOMPARE(binaryMessageReceivedSpy.count(), 0);
407     QCOMPARE(pongSpy.count(), 0);
408     QCOMPARE(bytesWrittenSpy.count(), 0);
409 }
410
411 void tst_QWebSocket::tst_sendTextMessage()
412 {
413     //TODO: will resolve in another commit
414 #ifndef Q_OS_WIN
415     EchoServer echoServer;
416
417     QWebSocket socket;
418
419     //should return 0 because socket is not open yet
420     QCOMPARE(socket.sendTextMessage(QStringLiteral("1234")), 0);
421
422     QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
423     QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString)));
424     QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool)));
425     QSignalSpy binaryMessageReceived(&socket, SIGNAL(binaryMessageReceived(QByteArray)));
426     QSignalSpy binaryFrameReceived(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool)));
427
428     socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
429                      QStringLiteral(":") + QString::number(echoServer.port())));
430
431     if (socketConnectedSpy.count() == 0)
432         QVERIFY(socketConnectedSpy.wait(500));
433     QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
434
435     socket.sendTextMessage(QStringLiteral("Hello world!"));
436
437     QVERIFY(textMessageReceived.wait(500));
438     QCOMPARE(textMessageReceived.count(), 1);
439     QCOMPARE(binaryMessageReceived.count(), 0);
440     QCOMPARE(binaryFrameReceived.count(), 0);
441     QList<QVariant> arguments = textMessageReceived.takeFirst();
442     QString messageReceived = arguments.at(0).toString();
443     QCOMPARE(messageReceived, QStringLiteral("Hello world!"));
444
445     QCOMPARE(textFrameReceived.count(), 1);
446     arguments = textFrameReceived.takeFirst();
447     QString frameReceived = arguments.at(0).toString();
448     bool isLastFrame = arguments.at(1).toBool();
449     QCOMPARE(frameReceived, QStringLiteral("Hello world!"));
450     QVERIFY(isLastFrame);
451
452     socket.close();
453
454     //QTBUG-36762: QWebSocket emits multiplied signals when socket was reopened
455     socketConnectedSpy.clear();
456     textMessageReceived.clear();
457     textFrameReceived.clear();
458
459     socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
460                      QStringLiteral(":") + QString::number(echoServer.port())));
461
462     if (socketConnectedSpy.count() == 0)
463         QVERIFY(socketConnectedSpy.wait(500));
464     QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
465
466     socket.sendTextMessage(QStringLiteral("Hello world!"));
467
468     QVERIFY(textMessageReceived.wait(500));
469     QCOMPARE(textMessageReceived.count(), 1);
470     QCOMPARE(binaryMessageReceived.count(), 0);
471     QCOMPARE(binaryFrameReceived.count(), 0);
472     arguments = textMessageReceived.takeFirst();
473     messageReceived = arguments.at(0).toString();
474     QCOMPARE(messageReceived, QStringLiteral("Hello world!"));
475
476     QCOMPARE(textFrameReceived.count(), 1);
477     arguments = textFrameReceived.takeFirst();
478     frameReceived = arguments.at(0).toString();
479     isLastFrame = arguments.at(1).toBool();
480     QCOMPARE(frameReceived, QStringLiteral("Hello world!"));
481     QVERIFY(isLastFrame);
482 #endif
483 }
484
485 void tst_QWebSocket::tst_sendBinaryMessage()
486 {
487     //TODO: will resolve in another commit
488 #ifndef Q_OS_WIN
489     EchoServer echoServer;
490
491     QWebSocket socket;
492
493     //should return 0 because socket is not open yet
494     QCOMPARE(socket.sendBinaryMessage(QByteArrayLiteral("1234")), 0);
495
496     QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
497     QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString)));
498     QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool)));
499     QSignalSpy binaryMessageReceived(&socket, SIGNAL(binaryMessageReceived(QByteArray)));
500     QSignalSpy binaryFrameReceived(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool)));
501
502     socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
503                      QStringLiteral(":") + QString::number(echoServer.port())));
504
505     if (socketConnectedSpy.count() == 0)
506         QVERIFY(socketConnectedSpy.wait(500));
507     QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
508
509     socket.sendBinaryMessage(QByteArrayLiteral("Hello world!"));
510
511     QVERIFY(binaryMessageReceived.wait(500));
512     QCOMPARE(textMessageReceived.count(), 0);
513     QCOMPARE(textFrameReceived.count(), 0);
514     QCOMPARE(binaryMessageReceived.count(), 1);
515     QList<QVariant> arguments = binaryMessageReceived.takeFirst();
516     QByteArray messageReceived = arguments.at(0).toByteArray();
517     QCOMPARE(messageReceived, QByteArrayLiteral("Hello world!"));
518
519     QCOMPARE(binaryFrameReceived.count(), 1);
520     arguments = binaryFrameReceived.takeFirst();
521     QByteArray frameReceived = arguments.at(0).toByteArray();
522     bool isLastFrame = arguments.at(1).toBool();
523     QCOMPARE(frameReceived, QByteArrayLiteral("Hello world!"));
524     QVERIFY(isLastFrame);
525
526     socket.close();
527
528     //QTBUG-36762: QWebSocket emits multiple signals when socket is reopened
529     socketConnectedSpy.clear();
530     binaryMessageReceived.clear();
531     binaryFrameReceived.clear();
532
533     socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
534                      QStringLiteral(":") + QString::number(echoServer.port())));
535
536     if (socketConnectedSpy.count() == 0)
537         QVERIFY(socketConnectedSpy.wait(500));
538     QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
539
540     socket.sendBinaryMessage(QByteArrayLiteral("Hello world!"));
541
542     QVERIFY(binaryMessageReceived.wait(500));
543     QCOMPARE(textMessageReceived.count(), 0);
544     QCOMPARE(textFrameReceived.count(), 0);
545     QCOMPARE(binaryMessageReceived.count(), 1);
546     arguments = binaryMessageReceived.takeFirst();
547     messageReceived = arguments.at(0).toByteArray();
548     QCOMPARE(messageReceived, QByteArrayLiteral("Hello world!"));
549
550     QCOMPARE(binaryFrameReceived.count(), 1);
551     arguments = binaryFrameReceived.takeFirst();
552     frameReceived = arguments.at(0).toByteArray();
553     isLastFrame = arguments.at(1).toBool();
554     QCOMPARE(frameReceived, QByteArrayLiteral("Hello world!"));
555     QVERIFY(isLastFrame);
556 #endif
557 }
558
559 void tst_QWebSocket::tst_errorString()
560 {
561     //Check for QTBUG-37228: QWebSocket returns "Unknown Error" for known errors
562     QWebSocket socket;
563
564     //check that the default error string is empty
565     QVERIFY(socket.errorString().isEmpty());
566
567     QSignalSpy errorSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
568
569     socket.open(QUrl(QStringLiteral("ws://someserver.on.mars:9999")));
570
571     if (errorSpy.count() == 0)
572         errorSpy.wait();
573     QCOMPARE(errorSpy.count(), 1);
574     QList<QVariant> arguments = errorSpy.takeFirst();
575     QAbstractSocket::SocketError socketError =
576             qvariant_cast<QAbstractSocket::SocketError>(arguments.at(0));
577     QCOMPARE(socketError, QAbstractSocket::HostNotFoundError);
578     QCOMPARE(socket.errorString(), QStringLiteral("Host not found"));
579 }
580
581 #ifndef QT_NO_NETWORKPROXY
582 void tst_QWebSocket::tst_setProxy()
583 {
584     // check if property assignment works as expected.
585     QWebSocket socket;
586     QCOMPARE(socket.proxy(), QNetworkProxy(QNetworkProxy::DefaultProxy));
587
588     QNetworkProxy proxy;
589     proxy.setPort(123);
590     socket.setProxy(proxy);
591     QCOMPARE(socket.proxy(), proxy);
592
593     proxy.setPort(321);
594     QCOMPARE(socket.proxy().port(), quint16(123));
595     socket.setProxy(proxy);
596     QCOMPARE(socket.proxy(), proxy);
597 }
598 #endif // QT_NO_NETWORKPROXY
599
600 QTEST_MAIN(tst_QWebSocket)
601
602 #include "tst_qwebsocket.moc"