#include "eetv4client.h" #include "eetv4signer.h" #include #include #include #include #include #include #include namespace { class MockEetServer : public QSslServer { public: explicit MockEetServer(const QByteArray &response) : m_response(response) { connect(this, &QSslServer::pendingConnectionAvailable, this, [this] { QSslSocket *socket = qobject_cast(nextPendingConnection()); if (socket == nullptr) { return; } connect(socket, &QSslSocket::readyRead, this, [this, socket] { const QByteArray request = socket->readAll(); const qsizetype bodyStart = request.indexOf("\r\n\r\n"); const QByteArray soap = bodyStart < 0 ? QByteArray() : request.mid(bodyStart + 4); QString verificationError; m_requestVerified = !soap.isEmpty() && EetV4Signer::verifySoap(soap, &verificationError); const QByteArray http = "HTTP/1.1 200 OK\r\nContent-Type: text/xml; charset=utf-8\r\n" "Content-Length: " + QByteArray::number(m_response.size()) + "\r\nConnection: close\r\n\r\n" + m_response; socket->write(http); socket->disconnectFromHost(); }); }); } bool requestVerified() const { return m_requestVerified; } private: QByteArray m_response; bool m_requestVerified{false}; }; } class EetV4ClientIntegrationTest : public QObject { Q_OBJECT private slots: void sendsSignedSaleAndParsesPok(); }; void EetV4ClientIntegrationTest::sendsSignedSaleAndParsesPok() { QTemporaryDir directory; QVERIFY(directory.isValid()); const QString keyPath = directory.filePath(QStringLiteral("key.pem")); const QString certPath = directory.filePath(QStringLiteral("certificate.pem")); const QString p12Path = directory.filePath(QStringLiteral("certificate.p12")); auto runOpenSsl = [](const QStringList &arguments) { QProcess process; process.start(QStringLiteral("openssl"), arguments); QVERIFY2(process.waitForFinished(30000), qPrintable(process.errorString())); QVERIFY2(process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0, process.readAllStandardError().constData()); }; runOpenSsl({QStringLiteral("req"), QStringLiteral("-x509"), QStringLiteral("-newkey"), QStringLiteral("rsa:2048"), QStringLiteral("-nodes"), QStringLiteral("-subj"), QStringLiteral("/CN=localhost"), QStringLiteral("-keyout"), keyPath, QStringLiteral("-out"), certPath, QStringLiteral("-days"), QStringLiteral("1")}); runOpenSsl({QStringLiteral("pkcs12"), QStringLiteral("-export"), QStringLiteral("-out"), p12Path, QStringLiteral("-inkey"), keyPath, QStringLiteral("-in"), certPath, QStringLiteral("-passout"), QStringLiteral("pass:test")}); const QByteArray unsignedResponse = "" "" "" "" "" "" ""; QString signingError; const QByteArray signedResponse = EetV4Signer::signSoap( unsignedResponse, p12Path, QByteArrayLiteral("test"), &signingError); QVERIFY2(!signedResponse.isEmpty(), qPrintable(signingError)); MockEetServer server(signedResponse); QSslConfiguration serverSsl = QSslConfiguration::defaultConfiguration(); QFile keyFile(keyPath); QFile certificateFile(certPath); QVERIFY(keyFile.open(QIODevice::ReadOnly)); QVERIFY(certificateFile.open(QIODevice::ReadOnly)); serverSsl.setPrivateKey(QSslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem)); serverSsl.setLocalCertificate(QSslCertificate(certificateFile.readAll(), QSsl::Pem)); server.setSslConfiguration(serverSsl); QVERIFY(server.listen(QHostAddress::LocalHost)); QSslConfiguration clientSsl = QSslConfiguration::defaultConfiguration(); clientSsl.setCaCertificates({serverSsl.localCertificate()}); EetV4Client client({ QUrl(QStringLiteral("https://localhost:%1/eet").arg(server.serverPort())), 5000, clientSsl }); EetV4SaleRequest request; request.sentAt = QDateTime::currentDateTime().toOffsetFromUtc(0); request.saleAt = request.sentAt; request.taxpayerEic = QStringLiteral("CZ123456789"); request.unitId = 1; request.cashRegisterId = QStringLiteral("KASA1"); request.receiptNumber = QStringLiteral("TEST-1"); QVERIFY(EetV4Amount::fromString(QStringLiteral("100.00"), &request.totalSale)); EetV4Response response; QString error; QVERIFY2(client.sendSale(request, p12Path, QByteArrayLiteral("test"), &response, &error), qPrintable(error)); QVERIFY(server.requestVerified()); QVERIFY(response.isSuccess()); QCOMPARE(response.pok, QStringLiteral("123e4567-e89b-42d3-a456-426614174000-01")); } QTEST_MAIN(EetV4ClientIntegrationTest) #include "eetv4client_integration_test.moc"