1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/**
* Copyright (c) 2016-2026 Governikus GmbH & Co. KG, Germany
*/
#include "PortFile.h"
#include "WebSocketHelper.h"
#include <QFile>
#include <QProcess>
#include <QtTest>
using namespace Qt::Literals::StringLiterals;
using namespace governikus;
class test_UiPluginWebSocket
: public QObject
{
Q_OBJECT
private:
static const int PROCESS_TIMEOUT = 30000;
QScopedPointer<QProcess> mApp2;
QScopedPointer<WebSocketHelper> mHelper;
private Q_SLOTS:
void initTestCase()
{
qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
}
void init()
{
QString path = QStringLiteral(AUSWEISAPP_BINARY_DIR);
QString app = path + "AusweisApp"_L1;
#ifdef Q_OS_WIN
app += ".exe"_L1;
#endif
QStringList args;
args << "--ui"_L1 << "websocket"_L1;
args << "--port"_L1 << "0"_L1;
#ifndef Q_OS_WIN
args << "-platform"_L1 << "offscreen"_L1;
#endif
mApp2.reset(new QProcess());
mApp2->setProgram(app);
mApp2->setWorkingDirectory(path);
mApp2->setArguments(args);
mApp2->start();
mApp2->waitForStarted(PROCESS_TIMEOUT);
QCOMPARE(mApp2->state(), QProcess::Running);
QFile portInfoFile(PortFile::getPortFilename(QString(), mApp2->processId(), QStringLiteral("AusweisApp")));
QTRY_COMPARE_WITH_TIMEOUT(portInfoFile.exists(), true, PROCESS_TIMEOUT); // clazy:exclude=qstring-allocations
QVERIFY(portInfoFile.open(QIODevice::ReadOnly));
quint16 webSocketPort = 0;
QTextStream(&portInfoFile) >> webSocketPort;
QVERIFY(webSocketPort > 0);
mHelper.reset(new WebSocketHelper(webSocketPort));
QTRY_VERIFY_WITH_TIMEOUT(mHelper->isConnected(), PROCESS_TIMEOUT);
}
void cleanup()
{
const QString portFile = PortFile::getPortFilename(QString(), mApp2->processId(), QStringLiteral("AusweisApp"));
QVERIFY(QFile::exists(portFile));
mHelper.reset();
QCOMPARE(mApp2->state(), QProcess::Running);
#ifndef Q_OS_WIN
// QProcess::terminate() sends WM_CLOSE on Windows. We can not handle this signal
// since it does not clearly indicate a quit request. It might simply be a closing
// window, too.
mApp2->terminate();
mApp2->waitForFinished(PROCESS_TIMEOUT);
#endif
if (mApp2->state() != QProcess::NotRunning)
{
mApp2->kill();
}
QTRY_COMPARE_WITH_TIMEOUT(mApp2->state(), QProcess::NotRunning, PROCESS_TIMEOUT); // clazy:exclude=qstring-allocations
#ifndef Q_OS_WIN
// There will never be a clean shutdown on Windows.
if (mApp2->exitCode() != 0)
{
qDebug().noquote() << "Error output from AusweisApp process:\n" << mApp2->readAllStandardError();
}
QCOMPARE(mApp2->exitCode(), 0);
#endif
#ifdef Q_OS_WIN
QFile::remove(portFile);
#endif
QVERIFY(!QFile::exists(portFile));
}
void runAndStop()
{
}
void getInfoAndApiLevel()
{
mHelper->sendMessage("{\"cmd\": \"GET_INFO\"}"_L1);
QVERIFY(mHelper->waitForMessage([](const QJsonObject& pMessage){
return pMessage["msg"_L1] == "INFO"_L1 &&
pMessage["VersionInfo"_L1].toObject()["Name"_L1] == QLatin1String("AusweisApp2");
}));
mHelper->sendMessage("{\"cmd\": \"GET_API_LEVEL\"}"_L1);
QVERIFY(mHelper->waitForMessage([](const QJsonObject& pMessage){
return pMessage["msg"_L1] == "API_LEVEL"_L1 &&
pMessage["available"_L1].toArray().size() >= 1;
}));
}
void tryLocalhostAuth()
{
#ifdef Q_OS_FREEBSD
QSKIP("Not supported");
#endif
mHelper->sendMessage("{\"cmd\": \"RUN_AUTH\", \"tcTokenURL\" : \"https://localhost/\"}"_L1);
QVERIFY(mHelper->waitForMessage([](const QJsonObject& pMessage){
return pMessage["msg"_L1] == "AUTH"_L1;
}));
QVERIFY(mHelper->waitForMessage([](const QJsonObject& pMessage){
return pMessage["result"_L1].toObject()["major"_L1].toString().endsWith("#error"_L1);
}));
}
};
QTEST_GUILESS_MAIN(test_UiPluginWebSocket)
#include "test_UiPluginWebSocket.moc"
|