diff --git a/server-sdk b/server-sdk index 5ee8276..a818055 160000 --- a/server-sdk +++ b/server-sdk @@ -1 +1 @@ -Subproject commit 5ee82764e7fdcd6566b7eceac985b42348e2efcd +Subproject commit a818055b75dc0de97e26be44cbbfd2e94516c09e diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index eadb3b9..55d818e 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -3,37 +3,73 @@ Q_LOGGING_CATEGORY(colnod, "colnod.api"); -ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const qint64 &lastSync, const bool &dryMode, const QString &userName, const QString &password) +ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const bool &dryMode, const QString &userName, const QString &password) :mReqMan(reqMan), mUserName(userName), mPassword(password), mDryMode(dryMode) { - mLastSync.set_timestamp(lastSync); - mData = std::make_shared(); - // ----------------------------------- mReqMan->setIgnoreSsl(true); // ----------------------------------- } -void ColnodAPI::downloadData() +void ColnodAPI::downloadData(const Timestamp &time) { // Have to get Login auto login = requestLogin(); connect(login.get(), &serversdk::Request::finished, this, [=](){ // Get login token - if (login->status() != 200) { - emit error(); + if (!checkRequest(login)) { + emit downloadDataFinished(nullptr); + return; } AuthToken token; token.fromJson(login->responseData()); authToken = token.id(); + auto data = std::make_shared(); + + auto errorHandler = [=](std::shared_ptr request){ + if (!checkRequest(request)) { + qWarning(colnod) << "ERROR during calling" << request->url() << ", request unsuccessful"; + mValid = false; + emit downloadDataFinished(nullptr); + } + else if (!checkResponse(request->responseData())) { + qWarning(colnod) << "Data from" << request->url() << "are invalid"; + mValid = false; + } + }; + // if I have all data emit downloadDataFinished connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady); - getTokensUpdated(mLastSync); - getTokensDeleted(mLastSync); - getSubjectsUpdated(mLastSync); - getSubjectsDeleted(mLastSync); + + auto tokensRequest = getTokensUpdated(time); + connect(tokensRequest.get(), &serversdk::Request::finished, errorHandler); + connect(tokensRequest.get(), &serversdk::Request::finished, [=](){ + saveUpdatedTokens(data, tokensRequest->responseData()); + emit partOfDataReady(data); + }); + + auto deletedTokensRequest = getTokensDeleted(time); + connect(deletedTokensRequest.get(), &serversdk::Request::finished, errorHandler); + connect(deletedTokensRequest.get(), &serversdk::Request::finished, [=](){ + saveDeletedTokens(data, deletedTokensRequest->responseData()); + emit partOfDataReady(data); + }); + + auto subjectsRequest = getSubjectsUpdated(time); + connect(subjectsRequest.get(), &serversdk::Request::finished, errorHandler); + connect(subjectsRequest.get(), &serversdk::Request::finished, [=](){ + saveUpdatedSubjects(data, subjectsRequest->responseData()); + emit partOfDataReady(data); + }); + + auto deletedSubjectsRequest = getSubjectsDeleted(time); + connect(deletedSubjectsRequest.get(), &serversdk::Request::finished, errorHandler); + connect(deletedSubjectsRequest.get(), &serversdk::Request::finished, [=](){ + saveDeletedSubjects(data, deletedSubjectsRequest->responseData()); + emit partOfDataReady(data); + }); }); } @@ -88,83 +124,39 @@ std::shared_ptr ColnodAPI::requestLogin() return loginRequest; } -void ColnodAPI::getTokensUpdated(const Timestamp &time) +std::shared_ptr ColnodAPI::getTokensUpdated(const Timestamp &time) { auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); - connect(request.get(), &serversdk::Request::finished, [=](){ - if (!checkRequest(request)) { - qWarning(colnod) << "ERROR during calling /TokenManager/getTokensUpdated, request unsuccessful"; - mValid = false; - } - else if (!checkResponse(request->responseData())) { - qWarning(colnod) << "Data from /TokenManager/getTokensUpdated are invalid"; - mValid = false; - } - saveUpdatedTokens(request->responseData()); - emit partOfDataReady(mData); - }); + return request; } -void ColnodAPI::getTokensDeleted(const Timestamp &time) +std::shared_ptr ColnodAPI::getTokensDeleted(const Timestamp &time) { auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); - connect(request.get(), &serversdk::Request::finished, [=](){ - if (!checkRequest(request)) { - qWarning(colnod) << "ERROR during calling /TokenManager/getTokensDeleted, request unsuccessful"; - mValid = false; - } - else if (!checkResponse(request->responseData())) { - qWarning(colnod) << "Data from /TokenManager/getTokensDeleted are invalid"; - mValid = false; - } - saveDeletedTokens(request->responseData()); - emit partOfDataReady(); - }); + return request; } -void ColnodAPI::getSubjectsUpdated(const Timestamp &time) +std::shared_ptr ColnodAPI::getSubjectsUpdated(const Timestamp &time) { auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); - connect(request.get(), &serversdk::Request::finished, [=](){ - if (!checkRequest(request)) { - qWarning(colnod) << "ERROR during calling /SubjectManager/getSubjectsUpdated, request unsuccessful"; - mValid = false; - } - else if (!checkResponse(request->responseData())) { - qWarning(colnod) << "Data from /SubjectManager/getSubjectsUpdated are invalid"; - mValid = false; - } - saveUpdatedSubjects(request->responseData()); - emit partOfDataReady(); - }); + return request; } -void ColnodAPI::getSubjectsDeleted(const Timestamp &time) +std::shared_ptr ColnodAPI::getSubjectsDeleted(const Timestamp &time) { auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData()); request->setUserName(authToken); mReqMan->processRequest(request); - connect(request.get(), &serversdk::Request::finished, [=](){ - if (!checkRequest(request)) { - qWarning(colnod) << "ERROR during calling /SubjectManager/getSubjectsDeleted, request unsuccessful"; - mValid = false; - } - else if (!checkResponse(request->responseData())) { - qWarning(colnod) << "Data from /SubjectManager/getSubjectsDeleted are invalid"; - mValid = false; - } - saveDeletedSubjects(request->responseData()); - emit partOfDataReady(); - }); + return request; } -void ColnodAPI::setTokens(const QHash> &tokens) +std::shared_ptr ColnodAPI::setTokens(const QHash> &tokens) { auto request = composeRequest("/TokenManager/setTokens", Token::tokensToColnodJson(tokens)); request->setUserName(authToken); @@ -183,9 +175,10 @@ void ColnodAPI::setTokens(const QHash> &tokens) emit partOfDataProcessFinished(); } }); + return request; } -void ColnodAPI::deleteTokens(const QList &ids) +std::shared_ptr ColnodAPI::deleteTokens(const QList &ids) { auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids)); request->setUserName(authToken); @@ -204,7 +197,7 @@ void ColnodAPI::deleteTokens(const QList &ids) emit partOfDataProcessFinished(); } }); - + return request; } std::shared_ptr ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data) @@ -257,19 +250,19 @@ void ColnodAPI::setUserName(const QString &userName) mUserName = userName; } -void ColnodAPI::areDataReady() +void ColnodAPI::areDataReady(std::shared_ptr data) { if (++amountData == 4) { qInfo(colnod) << tab << "-> COLNOD DATA:"; - qInfo(colnod) << tab << tab << mData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; - qInfo(colnod) << tab << tab << mData->deletedTokens.size() << "TOKENS DELETED"; - qInfo(colnod) << tab << tab << mData->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; - qInfo(colnod) << tab << tab << mData->deletedSubjects.size() << "SUBJECTS DELETED"; + qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; + qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; + qInfo(colnod) << tab << tab << data->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; + qInfo(colnod) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; qInfo(colnod) << dash; - emit downloadDataFinished(mData); - newData(); + amountData = 0; + emit downloadDataFinished(data); } } @@ -280,31 +273,31 @@ void ColnodAPI::isDataProcessFinished() } } -void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData) +void ColnodAPI::saveUpdatedTokens(std::shared_ptr data, const QByteArray &responseData) { - mData->loadTokensFromJson(responseData); + data->loadTokensFromJson(responseData); } -void ColnodAPI::saveDeletedTokens(const QByteArray &responseData) +void ColnodAPI::saveDeletedTokens(std::shared_ptr data, const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { - mData->deletedTokens.append(item.toString()); + data->deletedTokens.append(item.toString()); } } -void ColnodAPI::saveUpdatedSubjects(const QByteArray &responseData) +void ColnodAPI::saveUpdatedSubjects(std::shared_ptr data, const QByteArray &responseData) { - mData->loadSubjectsFormJson(responseData); + data->loadSubjectsFormJson(responseData); } -void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData) +void ColnodAPI::saveDeletedSubjects(std::shared_ptr data, const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { - mData->deletedSubjects.append(item.toString()); + data->deletedSubjects.append(item.toString()); } } diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index f75abbe..68ed360 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -23,6 +23,20 @@ class Timestamp : public serversdk::DatabaseTable { Q_OBJECT TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0) public: + Timestamp() = default; + explicit Timestamp(const Timestamp &time) + { + this->set_timestamp(time.timestamp()); + } + explicit Timestamp(qint64 time) + { + set_timestamp(time); + } + explicit Timestamp(QDateTime time) + { + set_timestamp(time.toMSecsSinceEpoch()); + } + QString toDateString() { return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); @@ -34,22 +48,22 @@ class ColnodAPI: public QObject Q_OBJECT public: ColnodAPI() = default; - ColnodAPI(serversdk::RequestManager* reqMan, const qint64 &lastSync = 0, const bool &dryMode = false, const QString &userName = "spaceti", const QString &password = "spaceti1"); + ColnodAPI(serversdk::RequestManager* reqManconst, const bool &dryMode = false, const QString &userName = "spaceti", const QString &password = "spaceti1"); - void downloadData(); + void downloadData(const Timestamp &time); void processData(const std::shared_ptr &data); // New approach std::shared_ptr requestLogin(); - void getTokensUpdated(const Timestamp &time); - void getTokensDeleted(const Timestamp &time); - void getSubjectsUpdated(const Timestamp &time); - void getSubjectsDeleted(const Timestamp &time); + std::shared_ptr getTokensUpdated(const Timestamp &time); + std::shared_ptr getTokensDeleted(const Timestamp &time); + std::shared_ptr getSubjectsUpdated(const Timestamp &time); + std::shared_ptr getSubjectsDeleted(const Timestamp &time); - void setTokens(const QHash> &tokens); - void deleteTokens(const QList &tokenIds); + std::shared_ptr setTokens(const QHash> &tokens); + std::shared_ptr deleteTokens(const QList &tokenIds); // Attributes QString userName() const; @@ -62,14 +76,14 @@ public: bool isValid(); private: - Q_SLOT void areDataReady(); + Q_SLOT void areDataReady(std::shared_ptr data); Q_SLOT void isDataProcessFinished(); private: - void saveUpdatedTokens(const QByteArray &responseData); - void saveUpdatedSubjects(const QByteArray &responseData); - void saveDeletedTokens(const QByteArray &responseData); - void saveDeletedSubjects(const QByteArray &responseData); + void saveUpdatedTokens(std::shared_ptr data, const QByteArray &responseData); + void saveUpdatedSubjects(std::shared_ptr data, const QByteArray &responseData); + void saveDeletedTokens(std::shared_ptr data, const QByteArray &responseData); + void saveDeletedSubjects(std::shared_ptr data, const QByteArray &responseData); void newData(); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index c56e7a9..4020c02 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -32,7 +32,7 @@ bool SyncManager::databaseInitialization() // here -> nothing can fail mlastSync.set_timestamp(database->getLastSync()); - colnod = std::make_shared(&reqMan, mlastSync.timestamp(), mDryMode); + colnod = std::make_shared(&reqMan, mDryMode); return true; } @@ -62,7 +62,7 @@ bool SyncManager::startSynchronization() // NOW I HAVE DATA FROM DATABASE - colnod->downloadData(); + colnod->downloadData(Timestamp(syncBegin)); connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr data) { if (!data) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; @@ -133,7 +133,7 @@ bool SyncManager::downloadData() connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); //connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); //database->downloadData(); - colnod->downloadData(); + //colnod->downloadData(); return res; } diff --git a/test/auto/auto.pro b/test/auto/auto.pro index d155315..3fa2a6d 100644 --- a/test/auto/auto.pro +++ b/test/auto/auto.pro @@ -2,4 +2,5 @@ TEMPLATE = subdirs SUBDIRS += \ database/tst_databaseapi.pro \ + colnod/tst_colnodapi.pro \ syncmanager/tst_syncmanager.pro \ diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp new file mode 100644 index 0000000..69d32e8 --- /dev/null +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -0,0 +1,113 @@ +#include + +#include "colnodapi.h" +#include "serversdk/request.h" +// add necessary includes here + +Q_DECLARE_METATYPE(std::shared_ptr) +Q_DECLARE_METATYPE(std::shared_ptr); + +class ColnodTest : public QObject +{ + Q_OBJECT +public: + ColnodTest() + { + qRegisterMetaType>(); + qRegisterMetaType>(); + } + +private slots: + void login(); + void getTokens(); + void download_data_test(); + void download_data_fail_test(); + +private: + QString getLoginToken(ColnodAPI &colnod); +}; + + + + +void ColnodTest::login() +{ + serversdk::RequestManager reqMan; + ColnodAPI colnod(&reqMan); + auto login = colnod.requestLogin(); + QSignalSpy spy(login.get(), &serversdk::Request::finished); + QCOMPARE(spy.count(), 0); + QVERIFY(spy.wait()); + QCOMPARE(spy.count(), 1); + QVERIFY(login->responseData().contains("id")); +} + +void ColnodTest::getTokens() +{ + serversdk::RequestManager reqMan; + ColnodAPI colnod(&reqMan); + + // get login token + auto login = colnod.requestLogin(); + QSignalSpy spy(login.get(), &serversdk::Request::finished); + spy.wait(); + QString token = getLoginToken(colnod); + Timestamp time(QDateTime::currentMSecsSinceEpoch()); + colnod.getTokensUpdated(time); +} + +void ColnodTest::download_data_test() +{ + serversdk::RequestManager reqMan; + ColnodAPI colnod(&reqMan); + { + QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + colnod.downloadData(Timestamp(1570190399259)); + QVERIFY(spy.wait()); + + auto data = qvariant_cast>(spy.at(0).at(0)); + QVERIFY(data); + + QVERIFY(data->updatedTokens.size() > 0); + QVERIFY(data->updatedTokens.contains("5e2f1260-da1c-441f-9644-24dfe3b97b2a")); + } + { + Timestamp time(QDateTime::currentMSecsSinceEpoch()); + colnod.downloadData(time); + QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + QVERIFY(spy.wait()); + auto data = qvariant_cast>(spy.at(0).at(0)); + QVERIFY(data); + + QVERIFY(data->updatedTokens.size() == 0); + } +} + +void ColnodTest::download_data_fail_test() +{ + serversdk::RequestManager reqMan; + ColnodAPI colnod(&reqMan, false, "spaceti", "wrong password"); + + Timestamp time(0); + QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + colnod.downloadData(time); + + QVERIFY(spy.wait()); + + auto data = qvariant_cast>(spy.at(0).at(0)); + + +} + +QString ColnodTest::getLoginToken(ColnodAPI &colnod) +{ + auto login = colnod.requestLogin(); + QSignalSpy spy(login.get(), &serversdk::Request::finished); + spy.wait(); + return login->responseData().mid(7,36); + +} + +QTEST_GUILESS_MAIN(ColnodTest) + +#include "tst_colnodapi.moc" diff --git a/test/auto/colnod/tst_colnodapi.pro b/test/auto/colnod/tst_colnodapi.pro new file mode 100644 index 0000000..b0e4013 --- /dev/null +++ b/test/auto/colnod/tst_colnodapi.pro @@ -0,0 +1,11 @@ +QT += testlib +QT -= gui + +CONFIG += qt console warn_on depend_includepath testcase +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_colnodapi.cpp + +include(../../test.pri)