Merge branch 'feat/unittest-colnod' into 'master'

Feat/unittest colnod

See merge request spaceti-app/integrations/acs/colnod-connector!28
This commit is contained in:
Filip Bucek 2019-11-28 14:11:43 +00:00
commit a88b200d5a
7 changed files with 230 additions and 98 deletions

@ -1 +1 @@
Subproject commit 5ee82764e7fdcd6566b7eceac985b42348e2efcd Subproject commit a818055b75dc0de97e26be44cbbfd2e94516c09e

View File

@ -3,37 +3,73 @@
Q_LOGGING_CATEGORY(colnod, "colnod.api"); 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) :mReqMan(reqMan), mUserName(userName), mPassword(password), mDryMode(dryMode)
{ {
mLastSync.set_timestamp(lastSync);
mData = std::make_shared<Data>();
// ----------------------------------- // -----------------------------------
mReqMan->setIgnoreSsl(true); mReqMan->setIgnoreSsl(true);
// ----------------------------------- // -----------------------------------
} }
void ColnodAPI::downloadData() void ColnodAPI::downloadData(const Timestamp &time)
{ {
// Have to get Login // Have to get Login
auto login = requestLogin(); auto login = requestLogin();
connect(login.get(), &serversdk::Request::finished, this, [=](){ connect(login.get(), &serversdk::Request::finished, this, [=](){
// Get login token // Get login token
if (login->status() != 200) { if (!checkRequest(login)) {
emit error(); emit downloadDataFinished(nullptr);
return;
} }
AuthToken token; AuthToken token;
token.fromJson(login->responseData()); token.fromJson(login->responseData());
authToken = token.id(); authToken = token.id();
auto data = std::make_shared<Data>();
auto errorHandler = [=](std::shared_ptr<serversdk::Request> 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 // if I have all data emit downloadDataFinished
connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady); connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady);
getTokensUpdated(mLastSync);
getTokensDeleted(mLastSync); auto tokensRequest = getTokensUpdated(time);
getSubjectsUpdated(mLastSync); connect(tokensRequest.get(), &serversdk::Request::finished, errorHandler);
getSubjectsDeleted(mLastSync); 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<serversdk::Request> ColnodAPI::requestLogin()
return loginRequest; return loginRequest;
} }
void ColnodAPI::getTokensUpdated(const Timestamp &time) std::shared_ptr<serversdk::Request> ColnodAPI::getTokensUpdated(const Timestamp &time)
{ {
auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData()); auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData());
request->setUserName(authToken); request->setUserName(authToken);
mReqMan->processRequest(request); mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){ return request;
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);
});
} }
void ColnodAPI::getTokensDeleted(const Timestamp &time) std::shared_ptr<serversdk::Request> ColnodAPI::getTokensDeleted(const Timestamp &time)
{ {
auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData()); auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData());
request->setUserName(authToken); request->setUserName(authToken);
mReqMan->processRequest(request); mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){ return request;
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();
});
} }
void ColnodAPI::getSubjectsUpdated(const Timestamp &time) std::shared_ptr<serversdk::Request> ColnodAPI::getSubjectsUpdated(const Timestamp &time)
{ {
auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData()); auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData());
request->setUserName(authToken); request->setUserName(authToken);
mReqMan->processRequest(request); mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){ return request;
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();
});
} }
void ColnodAPI::getSubjectsDeleted(const Timestamp &time) std::shared_ptr<serversdk::Request> ColnodAPI::getSubjectsDeleted(const Timestamp &time)
{ {
auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData()); auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData());
request->setUserName(authToken); request->setUserName(authToken);
mReqMan->processRequest(request); mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){ return request;
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();
});
} }
void ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens) std::shared_ptr<serversdk::Request> ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
{ {
auto request = composeRequest("/TokenManager/setTokens", Token::tokensToColnodJson(tokens)); auto request = composeRequest("/TokenManager/setTokens", Token::tokensToColnodJson(tokens));
request->setUserName(authToken); request->setUserName(authToken);
@ -183,9 +175,10 @@ void ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
emit partOfDataProcessFinished(); emit partOfDataProcessFinished();
} }
}); });
return request;
} }
void ColnodAPI::deleteTokens(const QList<QString> &ids) std::shared_ptr<serversdk::Request> ColnodAPI::deleteTokens(const QList<QString> &ids)
{ {
auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids)); auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids));
request->setUserName(authToken); request->setUserName(authToken);
@ -204,7 +197,7 @@ void ColnodAPI::deleteTokens(const QList<QString> &ids)
emit partOfDataProcessFinished(); emit partOfDataProcessFinished();
} }
}); });
return request;
} }
std::shared_ptr<serversdk::Request> ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data) std::shared_ptr<serversdk::Request> ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data)
@ -257,19 +250,19 @@ void ColnodAPI::setUserName(const QString &userName)
mUserName = userName; mUserName = userName;
} }
void ColnodAPI::areDataReady() void ColnodAPI::areDataReady(std::shared_ptr<Data> data)
{ {
if (++amountData == 4) { if (++amountData == 4) {
qInfo(colnod) << tab << "-> COLNOD DATA:"; qInfo(colnod) << tab << "-> COLNOD DATA:";
qInfo(colnod) << tab << tab << mData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED";
qInfo(colnod) << tab << tab << mData->deletedTokens.size() << "TOKENS DELETED"; qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED";
qInfo(colnod) << tab << tab << mData->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; qInfo(colnod) << tab << tab << data->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED";
qInfo(colnod) << tab << tab << mData->deletedSubjects.size() << "SUBJECTS DELETED"; qInfo(colnod) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED";
qInfo(colnod) << dash; qInfo(colnod) << dash;
emit downloadDataFinished(mData); amountData = 0;
newData(); emit downloadDataFinished(data);
} }
} }
@ -280,31 +273,31 @@ void ColnodAPI::isDataProcessFinished()
} }
} }
void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData) void ColnodAPI::saveUpdatedTokens(std::shared_ptr<Data> data, const QByteArray &responseData)
{ {
mData->loadTokensFromJson(responseData); data->loadTokensFromJson(responseData);
} }
void ColnodAPI::saveDeletedTokens(const QByteArray &responseData) void ColnodAPI::saveDeletedTokens(std::shared_ptr<Data> data, const QByteArray &responseData)
{ {
QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray(); QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) { 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> data, const QByteArray &responseData)
{ {
mData->loadSubjectsFormJson(responseData); data->loadSubjectsFormJson(responseData);
} }
void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData) void ColnodAPI::saveDeletedSubjects(std::shared_ptr<Data> data, const QByteArray &responseData)
{ {
QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray(); QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) { for (QJsonValueRef item : items) {
mData->deletedSubjects.append(item.toString()); data->deletedSubjects.append(item.toString());
} }
} }

View File

@ -23,6 +23,20 @@ class Timestamp : public serversdk::DatabaseTable {
Q_OBJECT Q_OBJECT
TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0) TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0)
public: 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() QString toDateString()
{ {
return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz");
@ -34,22 +48,22 @@ class ColnodAPI: public QObject
Q_OBJECT Q_OBJECT
public: public:
ColnodAPI() = default; 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> &data); void processData(const std::shared_ptr<Data> &data);
// New approach // New approach
std::shared_ptr<serversdk::Request> requestLogin(); std::shared_ptr<serversdk::Request> requestLogin();
void getTokensUpdated(const Timestamp &time); std::shared_ptr<serversdk::Request> getTokensUpdated(const Timestamp &time);
void getTokensDeleted(const Timestamp &time); std::shared_ptr<serversdk::Request> getTokensDeleted(const Timestamp &time);
void getSubjectsUpdated(const Timestamp &time); std::shared_ptr<serversdk::Request> getSubjectsUpdated(const Timestamp &time);
void getSubjectsDeleted(const Timestamp &time); std::shared_ptr<serversdk::Request> getSubjectsDeleted(const Timestamp &time);
void setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens); std::shared_ptr<serversdk::Request> setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens);
void deleteTokens(const QList<QString> &tokenIds); std::shared_ptr<serversdk::Request> deleteTokens(const QList<QString> &tokenIds);
// Attributes // Attributes
QString userName() const; QString userName() const;
@ -62,14 +76,14 @@ public:
bool isValid(); bool isValid();
private: private:
Q_SLOT void areDataReady(); Q_SLOT void areDataReady(std::shared_ptr<Data> data);
Q_SLOT void isDataProcessFinished(); Q_SLOT void isDataProcessFinished();
private: private:
void saveUpdatedTokens(const QByteArray &responseData); void saveUpdatedTokens(std::shared_ptr<Data> data, const QByteArray &responseData);
void saveUpdatedSubjects(const QByteArray &responseData); void saveUpdatedSubjects(std::shared_ptr<Data> data, const QByteArray &responseData);
void saveDeletedTokens(const QByteArray &responseData); void saveDeletedTokens(std::shared_ptr<Data> data, const QByteArray &responseData);
void saveDeletedSubjects(const QByteArray &responseData); void saveDeletedSubjects(std::shared_ptr<Data> data, const QByteArray &responseData);
void newData(); void newData();

View File

@ -32,7 +32,7 @@ bool SyncManager::databaseInitialization()
// here -> nothing can fail // here -> nothing can fail
mlastSync.set_timestamp(database->getLastSync()); mlastSync.set_timestamp(database->getLastSync());
colnod = std::make_shared<ColnodAPI>(&reqMan, mlastSync.timestamp(), mDryMode); colnod = std::make_shared<ColnodAPI>(&reqMan, mDryMode);
return true; return true;
} }
@ -62,7 +62,7 @@ bool SyncManager::startSynchronization()
// NOW I HAVE DATA FROM DATABASE // NOW I HAVE DATA FROM DATABASE
colnod->downloadData(); colnod->downloadData(Timestamp(syncBegin));
connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr<Data> data) { connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr<Data> data) {
if (!data) { if (!data) {
qCritical(syncmanager) << "Not possible to get correct data from colnod"; 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(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
//connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); //connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
//database->downloadData(); //database->downloadData();
colnod->downloadData(); //colnod->downloadData();
return res; return res;
} }

View File

@ -2,4 +2,5 @@ TEMPLATE = subdirs
SUBDIRS += \ SUBDIRS += \
database/tst_databaseapi.pro \ database/tst_databaseapi.pro \
colnod/tst_colnodapi.pro \
syncmanager/tst_syncmanager.pro \ syncmanager/tst_syncmanager.pro \

View File

@ -0,0 +1,113 @@
#include <QtTest>
#include "colnodapi.h"
#include "serversdk/request.h"
// add necessary includes here
Q_DECLARE_METATYPE(std::shared_ptr<Data>)
Q_DECLARE_METATYPE(std::shared_ptr<serversdk::Request>);
class ColnodTest : public QObject
{
Q_OBJECT
public:
ColnodTest()
{
qRegisterMetaType<std::shared_ptr<Data>>();
qRegisterMetaType<std::shared_ptr<serversdk::Request>>();
}
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<std::shared_ptr<Data>>(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<std::shared_ptr<Data>>(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<std::shared_ptr<Data>>(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"

View File

@ -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)