| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #include <QLoggingCategory>
- #include <QSignalSpy>
- #include <QTest>
- #include <cstdint>
- #include <functional>
- #include "pushnotificationstestutils.h"
- #include "pushnotifications.h"
- Q_LOGGING_CATEGORY(lcFakeWebSocketServer, "nextcloud.test.fakewebserver", QtInfoMsg)
- FakeWebSocketServer::FakeWebSocketServer(quint16 port, QObject *parent)
- : QObject(parent)
- , _webSocketServer(new QWebSocketServer(QStringLiteral("Fake Server"), QWebSocketServer::NonSecureMode, this))
- {
- if (!_webSocketServer->listen(QHostAddress::Any, port)) {
- Q_UNREACHABLE();
- }
- connect(_webSocketServer, &QWebSocketServer::newConnection, this, &FakeWebSocketServer::onNewConnection);
- connect(_webSocketServer, &QWebSocketServer::closed, this, &FakeWebSocketServer::closed);
- qCInfo(lcFakeWebSocketServer) << "Open fake websocket server on port:" << port;
- _processTextMessageSpy = std::make_unique<QSignalSpy>(this, &FakeWebSocketServer::processTextMessage);
- }
- FakeWebSocketServer::~FakeWebSocketServer()
- {
- close();
- }
- QWebSocket *FakeWebSocketServer::authenticateAccount(const OCC::AccountPtr account, std::function<void(OCC::PushNotifications *pushNotifications)> beforeAuthentication, std::function<void(void)> afterAuthentication)
- {
- const auto pushNotifications = account->pushNotifications();
- Q_ASSERT(pushNotifications);
- QSignalSpy readySpy(pushNotifications, &OCC::PushNotifications::ready);
- beforeAuthentication(pushNotifications);
- // Wait for authentication
- if (!waitForTextMessages()) {
- return nullptr;
- }
- // Right authentication data should be sent
- if (textMessagesCount() != 2) {
- return nullptr;
- }
- const auto socket = socketForTextMessage(0);
- const auto userSent = textMessage(0);
- const auto passwordSent = textMessage(1);
- if (userSent != account->credentials()->user() || passwordSent != account->credentials()->password()) {
- return nullptr;
- }
- // Sent authenticated
- socket->sendTextMessage("authenticated");
- // Wait for ready signal
- readySpy.wait();
- if (readySpy.count() != 1 || !account->pushNotifications()->isReady()) {
- return nullptr;
- }
- afterAuthentication();
- return socket;
- }
- void FakeWebSocketServer::close()
- {
- if (_webSocketServer->isListening()) {
- qCInfo(lcFakeWebSocketServer) << "Close fake websocket server";
- _webSocketServer->close();
- qDeleteAll(_clients.begin(), _clients.end());
- }
- }
- void FakeWebSocketServer::processTextMessageInternal(const QString &message)
- {
- auto client = qobject_cast<QWebSocket *>(sender());
- emit processTextMessage(client, message);
- }
- void FakeWebSocketServer::onNewConnection()
- {
- qCInfo(lcFakeWebSocketServer) << "New connection on fake websocket server";
- auto socket = _webSocketServer->nextPendingConnection();
- connect(socket, &QWebSocket::textMessageReceived, this, &FakeWebSocketServer::processTextMessageInternal);
- connect(socket, &QWebSocket::disconnected, this, &FakeWebSocketServer::socketDisconnected);
- _clients << socket;
- }
- void FakeWebSocketServer::socketDisconnected()
- {
- qCInfo(lcFakeWebSocketServer) << "Socket disconnected";
- auto client = qobject_cast<QWebSocket *>(sender());
- if (client) {
- _clients.removeAll(client);
- client->deleteLater();
- }
- }
- bool FakeWebSocketServer::waitForTextMessages() const
- {
- return _processTextMessageSpy->wait();
- }
- uint32_t FakeWebSocketServer::textMessagesCount() const
- {
- return _processTextMessageSpy->count();
- }
- QString FakeWebSocketServer::textMessage(int messageNumber) const
- {
- Q_ASSERT(0 <= messageNumber && messageNumber < _processTextMessageSpy->count());
- return _processTextMessageSpy->at(messageNumber).at(1).toString();
- }
- QWebSocket *FakeWebSocketServer::socketForTextMessage(int messageNumber) const
- {
- Q_ASSERT(0 <= messageNumber && messageNumber < _processTextMessageSpy->count());
- return _processTextMessageSpy->at(messageNumber).at(0).value<QWebSocket *>();
- }
- void FakeWebSocketServer::clearTextMessages()
- {
- _processTextMessageSpy->clear();
- }
- OCC::AccountPtr FakeWebSocketServer::createAccount(const QString &username, const QString &password)
- {
- auto account = OCC::Account::create();
- QStringList typeList;
- typeList.append("files");
- typeList.append("activities");
- typeList.append("notifications");
- QString websocketUrl("ws://localhost:12345");
- QVariantMap endpointsMap;
- endpointsMap["websocket"] = websocketUrl;
- QVariantMap notifyPushMap;
- notifyPushMap["type"] = typeList;
- notifyPushMap["endpoints"] = endpointsMap;
- QVariantMap capabilitiesMap;
- capabilitiesMap["notify_push"] = notifyPushMap;
- account->setCapabilities(capabilitiesMap);
- auto credentials = new CredentialsStub(username, password);
- account->setCredentials(credentials);
- return account;
- }
- CredentialsStub::CredentialsStub(const QString &user, const QString &password)
- : _user(user)
- , _password(password)
- {
- }
- QString CredentialsStub::authType() const
- {
- return "";
- }
- QString CredentialsStub::user() const
- {
- return _user;
- }
- QString CredentialsStub::password() const
- {
- return _password;
- }
- QNetworkAccessManager *CredentialsStub::createQNAM() const
- {
- return nullptr;
- }
- bool CredentialsStub::ready() const
- {
- return false;
- }
- void CredentialsStub::fetchFromKeychain() { }
- void CredentialsStub::askFromUser() { }
- bool CredentialsStub::stillValid(QNetworkReply * /*reply*/)
- {
- return false;
- }
- void CredentialsStub::persist() { }
- void CredentialsStub::invalidateToken() { }
- void CredentialsStub::forgetSensitiveData() { }
|