diff --git a/cmake/Testing.cmake b/cmake/Testing.cmake index 1b67f68f4..082d221f0 100644 --- a/cmake/Testing.cmake +++ b/cmake/Testing.cmake @@ -21,4 +21,5 @@ endfunction() auto_test(core toxpk) auto_test(core toxid) auto_test(chatlog textformatter) +auto_test(net toxmedata) auto_test(platform posixsignalnotifier) diff --git a/test/net/toxmedata_test.cpp b/test/net/toxmedata_test.cpp new file mode 100644 index 000000000..031e376df --- /dev/null +++ b/test/net/toxmedata_test.cpp @@ -0,0 +1,289 @@ +/* + Copyright © 2017 by The qTox Project Contributors + + This file is part of qTox, a Qt-based graphical interface for Tox. + + qTox is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + qTox is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with qTox. If not, see . +*/ + +#include "src/net/toxmedata.h" + +#include + +#include +#include +#include +#include + +const QByteArray testToxId = + QByteArrayLiteral("\xC7\x71\x9C\x68\x08\xC1\x4B\x77\x34\x80\x04\x95\x6D\x1D\x98\x04" + "\x6C\xE0\x9A\x34\x37\x0E\x76\x08\x15\x0E\xAD\x74\xC3\x81\x5D\x30" + "\xC8\xBA\x3A\xB9\xBE\xB9"); +const QByteArray testPublicKey = + QByteArrayLiteral("\xC7\x71\x9C\x68\x08\xC1\x4B\x77\x34\x80\x04\x95\x6D\x1D\x98\x04" + "\x6C\xE0\x9A\x34\x37\x0E\x76\x08\x15\x0E\xAD\x74\xC3\x81\x5D\x30"); + +class TestToxmeData : public QObject +{ + Q_OBJECT +private slots: + void parsePublicKeyTest(); + void encryptedJsonTest(); + void lookupRequestTest(); + + void lookup_data(); + void lookup(); + + void extractCode_data(); + void extractCode(); + + void createAddressRequest(); + + void getPassTest_data(); + void getPassTest(); + + void deleteAddressRequestTest(); +}; + +/** + * @brief Test if parse public key works correctly. + */ +void TestToxmeData::parsePublicKeyTest() +{ + ToxmeData data; + QString publicKeyStr = testPublicKey.toHex(); + QString json = QStringLiteral(R"({"key": "%1"})").arg(publicKeyStr); + QByteArray result = data.parsePublicKey(json); + QCOMPARE(result, testPublicKey); + + json = QStringLiteral("Some wrong string"); + result = data.parsePublicKey(json); + QVERIFY(result.isEmpty()); +} + +/** + * @brief Test if generation action json with encrypted payload is correct. + */ +void TestToxmeData::encryptedJsonTest() +{ + ToxmeData data; + int action = 123; + QByteArray encrypted{QStringLiteral("sometext").toLatin1()}; + QByteArray nonce{QStringLiteral("nonce").toLatin1()}; + QString text = data.encryptedJson(action, testPublicKey, encrypted, nonce); + QJsonObject json = QJsonDocument::fromJson(text.toLatin1()).object(); + + int actionRes = json["action"].toInt(); + QCOMPARE(actionRes, 123); + + QByteArray pkRes = QByteArray::fromHex(json["public_key"].toString().toLatin1()); + QCOMPARE(pkRes, testPublicKey); + + QByteArray encRes = QByteArray::fromBase64(json["encrypted"].toString().toLatin1()); + QCOMPARE(encRes, encrypted); + + QByteArray nonceRes = QByteArray::fromBase64(json["nonce"].toString().toLatin1()); + QCOMPARE(nonceRes, nonce); +} + +/** + * @brief Test if request for lookup generated correctly. + */ +void TestToxmeData::lookupRequestTest() +{ + ToxmeData data; + QString json = QStringLiteral(R"({"action":3,"name":"testname"})"); + QString result = data.lookupRequest("testname"); + QCOMPARE(result, json); +} + +Q_DECLARE_METATYPE(ToxId) + +/** + * @brief Data function for lookup test. + */ +void TestToxmeData::lookup_data() +{ + qRegisterMetaType("ToxId"); + QTest::addColumn("input"); + QTest::addColumn("result"); + QString sToxId = testToxId.toHex(); + + QTest::newRow("Valid ToxId") << QStringLiteral(R"({"tox_id": "%1"})").arg(sToxId) + << ToxId(testToxId); + + QTest::newRow("Invalid ToxId") << QStringLiteral(R"({"tox_id": "SomeTextHere"})") + << ToxId{}; + QTest::newRow("Not json") << QStringLiteral("Not json string") + << ToxId{}; +} + +/** + * @brief Test if ToxId parsed from lookup response correcly. + */ +void TestToxmeData::lookup() +{ + QFETCH(QString, input); + QFETCH(ToxId, result); + ToxmeData data; + ToxId toxId = data.lookup(input); + QCOMPARE(result, toxId); +} + +Q_DECLARE_METATYPE(ToxmeData::ExecCode) + +/** + * @brief Data function for extractCode test. + */ +void TestToxmeData::extractCode_data() +{ + qRegisterMetaType("ToxmeData::ExecCode"); + QTest::addColumn("input"); + QTest::addColumn("result"); + + QTest::newRow("Custom code") << QStringLiteral(R"({"c": 123})") + << ToxmeData::ExecCode(123); + QTest::newRow("Ok code") << QStringLiteral(R"({"c": 0})") + << ToxmeData::ExecCode::Ok; + + QTest::newRow("String code") << QStringLiteral(R"({"c": "string here"})") + << ToxmeData::ExecCode::IncorrectResponse; + QTest::newRow("Invalid code") << QStringLiteral(R"({"c": text})") + << ToxmeData::ExecCode::IncorrectResponse; + QTest::newRow("Not json") << QStringLiteral("Not json string") + << ToxmeData::ExecCode::ServerError; +} + +/** + * @brief Test if exec code extracts correctly. + */ +void TestToxmeData::extractCode() +{ + QFETCH(QString, input); + QFETCH(ToxmeData::ExecCode, result); + ToxmeData data; + ToxmeData::ExecCode code = data.extractCode(input); + QCOMPARE(result, code); +} + +/** + * @brief Test if request for address creation is correct. + */ +void TestToxmeData::createAddressRequest() +{ + ToxmeData data; + ToxId id{testToxId}; + QString name{"Test address"}; + QString bio{"Bio text"}; + bool keepPrivate = true; + int timestamp = static_cast(time(nullptr)); + QString text = data.createAddressRequest(id, name, bio, keepPrivate); + QJsonObject json = QJsonDocument::fromJson(text.toLatin1()).object(); + + QByteArray toxIdData = QByteArray::fromHex(json["tox_id"].toString().toLatin1()); + ToxId toxIdRes{toxIdData}; + QCOMPARE(toxIdRes, id); + + QString nameRes = json["name"].toString(); + QCOMPARE(nameRes, name); + + bool privRes = json["privacy"].toInt(); + QCOMPARE(privRes, privRes); + + QString bioRes = json["bio"].toString(); + QCOMPARE(bioRes, bio); + + int timeRes = json["timestamp"].toInt(); + // Test will be failed if `createAddressRequest` will take more + // than 100 seconds + QVERIFY(qAbs(timeRes - timestamp) < 100); +} + +/** + * @brief Data function for getPassTest. + */ +void TestToxmeData::getPassTest_data() +{ + qRegisterMetaType("ToxmeData::ExecCode"); + QTest::addColumn("input"); + QTest::addColumn("result"); + QTest::addColumn("code"); + + QTest::newRow("Valid password") << QStringLiteral(R"({"password": "123qwe"})") + << QStringLiteral("123qwe") + << ToxmeData::ExecCode::Ok; + + QTest::newRow("Null password") << QStringLiteral(R"({"password": null})") + << QStringLiteral("") + << ToxmeData::ExecCode::Updated; + + QTest::newRow("Valid password with null") << QStringLiteral(R"({"password": "null"})") + << QStringLiteral("null") + << ToxmeData::ExecCode::Ok; + + // ERROR: password value with invalid text, but started with 'null' interpreted as Update +#if 0 + QTest::newRow("Invalid null password") << QStringLiteral(R"({"password": nulla})") + << QStringLiteral("") + << ToxmeData::ExecCode::IncorrectResponse; +#endif + + QTest::newRow("Invalid int password") << QStringLiteral(R"({"password": 123})") + << QStringLiteral("") + << ToxmeData::ExecCode::IncorrectResponse; + + QTest::newRow("Not json") << QStringLiteral("Not json") + << QStringLiteral("") + << ToxmeData::ExecCode::NoPassword; + +} + +/** + * @brief Test if password extraction is correct. + */ +void TestToxmeData::getPassTest() +{ + QFETCH(QString, input); + QFETCH(QString, result); + QFETCH(ToxmeData::ExecCode, code); + + ToxmeData data; + ToxmeData::ExecCode resCode = ToxmeData::ExecCode::Ok; + QString password = data.getPass(input, resCode); + QCOMPARE(password, result); + QCOMPARE(resCode, code); +} + +/** + * @brief Test if request for address deletation generated correct. + */ +void TestToxmeData::deleteAddressRequestTest() +{ + ToxmeData data; + ToxPk pk{testPublicKey}; + int timestamp = static_cast(time(nullptr)); + QString text = data.deleteAddressRequest(pk); + QJsonObject json = QJsonDocument::fromJson(text.toLatin1()).object(); + + QByteArray pkRes = QByteArray::fromHex(json["public_key"].toString().toLatin1()); + QCOMPARE(pkRes, testPublicKey); + + int timeRes = json["timestamp"].toInt(); + // Test will be failed if `deleteAddressRequest` will take more + // than 100 seconds + QVERIFY(qAbs(timeRes - timestamp) < 100); +} + +QTEST_GUILESS_MAIN(TestToxmeData) +#include "toxmedata_test.moc"