forked from ondra/colnod-connector
unittest: data driven testing for tokens and prepareData ( failing )
This commit is contained in:
parent
f3077d9f0a
commit
e8e8184add
@ -92,7 +92,7 @@ bool SyncManager::startSynchronization()
|
||||
|
||||
|
||||
connect(this, &SyncManager::dataReady, [=](){
|
||||
prepareData();
|
||||
//prepareData();
|
||||
|
||||
connect(this, &SyncManager::dataProcessFinished, [=](){
|
||||
|
||||
@ -305,7 +305,7 @@ std::unique_ptr<PreparedData> SyncManager::prepareDataUsindOld(const std::shared
|
||||
// Prepare data
|
||||
auto preparedData = std::make_unique<PreparedData>();
|
||||
preparedData->colnodData = cloneColnodDataToProcess;
|
||||
preparedData->databaseData = databaseDataToProcess;
|
||||
preparedData->databaseData = cloneDatabaseDataToProcess;
|
||||
|
||||
return preparedData;
|
||||
}
|
||||
@ -319,7 +319,7 @@ bool SyncManager::downloadData()
|
||||
qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):";
|
||||
qInfo(syncmanager) << dash;
|
||||
|
||||
connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
|
||||
//connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
|
||||
//connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
|
||||
//database->downloadData();
|
||||
//colnod->downloadData();
|
||||
@ -327,96 +327,6 @@ bool SyncManager::downloadData()
|
||||
return res;
|
||||
}
|
||||
|
||||
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
|
||||
bool SyncManager::prepareData()
|
||||
{
|
||||
qInfo(syncmanager) << equals;
|
||||
qInfo(syncmanager) << "PREPARING DATA -> BEGIN";
|
||||
qInfo(syncmanager) << dash;
|
||||
qInfo(syncmanager) << "Resolve conflicts ( changes on same item on both Colnod and DB ):";
|
||||
qInfo(syncmanager) << dash;
|
||||
|
||||
|
||||
Q_ASSERT(colnodData);
|
||||
Q_ASSERT(databaseData);
|
||||
|
||||
|
||||
// TODO: why copy data?
|
||||
colnodDataToProcess = std::make_shared<Data>(*colnodData);
|
||||
databaseDataToProcess = std::make_shared<Data>(*databaseData);
|
||||
|
||||
QList<QString> conflicts;
|
||||
QList<QString> alreadySynced;
|
||||
|
||||
// check modifed tokens from colnod, dont want update token, if it was edited in db after or has been already synced
|
||||
for (const auto &colnodToken : colnodDataToProcess->updatedTokens) {
|
||||
if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) {
|
||||
// updated in db later
|
||||
if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) {
|
||||
conflicts.append(colnodToken->id());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto token = database->getToken(colnodToken->id());
|
||||
if ( token )
|
||||
// alredy synced ( tokens are same )
|
||||
if (token == colnodToken)
|
||||
alreadySynced.append(colnodToken->id());
|
||||
}
|
||||
// remove tokens which should be not updated
|
||||
for (const auto &id : conflicts)
|
||||
colnodDataToProcess->updatedTokens.remove(id);
|
||||
for (const auto &id : alreadySynced)
|
||||
colnodDataToProcess->updatedTokens.remove(id);
|
||||
|
||||
qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:";
|
||||
qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE TOO";
|
||||
qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED";
|
||||
|
||||
|
||||
|
||||
conflicts.clear();
|
||||
|
||||
// chech for already deleted ( in previous synced tokens were deleted from colnod, so it come to this sync but we dont want to sync it again
|
||||
for (const auto &id : colnodDataToProcess->deletedTokens) {
|
||||
if (database->isAlreadyDeleted(id)) {
|
||||
conflicts.append(id);
|
||||
}
|
||||
}
|
||||
for (const auto &id : conflicts) {
|
||||
colnodDataToProcess->deletedTokens.removeOne(id);
|
||||
}
|
||||
|
||||
qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ALREADY DELETED";
|
||||
qInfo(syncmanager) << dash;
|
||||
|
||||
conflicts.clear();
|
||||
|
||||
// chech modified from db, remove token if it was edited in colnod later
|
||||
for (const auto &databaseToken : databaseDataToProcess->updatedTokens) {
|
||||
if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) {
|
||||
if (databaseToken < colnodDataToProcess->updatedTokens.value(databaseToken->id()))
|
||||
conflicts.append(databaseToken->id());
|
||||
}
|
||||
else {
|
||||
// restriction cauesed by colnod rest api
|
||||
if (databaseToken->description() != "mobile") {
|
||||
qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be ";
|
||||
conflicts.append(databaseToken->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &id : conflicts)
|
||||
colnodDataToProcess->updatedTokens.remove(id);
|
||||
|
||||
qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:";
|
||||
qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN IN COLNOD TOO";
|
||||
qInfo(syncmanager) << dash;
|
||||
|
||||
qInfo(syncmanager) << "PREPARING DATA -> FINISHED";
|
||||
qInfo(syncmanager) << equals;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SyncManager::processData()
|
||||
{
|
||||
@ -454,15 +364,3 @@ void SyncManager::areDataReady()
|
||||
emit dataReady();
|
||||
}
|
||||
}
|
||||
|
||||
void SyncManager::saveColnodData(const std::shared_ptr<Data> &data)
|
||||
{
|
||||
colnodData = data;
|
||||
areDataReady();
|
||||
}
|
||||
|
||||
void SyncManager::saveDatabaseData(const std::shared_ptr<Data> &data)
|
||||
{
|
||||
databaseData = data;
|
||||
areDataReady();
|
||||
}
|
||||
|
||||
@ -32,14 +32,12 @@ private:
|
||||
void initNewToken(const std::shared_ptr<Token>& token);
|
||||
|
||||
bool downloadData();
|
||||
bool prepareData();
|
||||
//bool prepareData();
|
||||
bool processData();
|
||||
void updateLastUpdate(qint64 syncBegin);
|
||||
|
||||
|
||||
private:
|
||||
Q_SLOT void saveColnodData(const std::shared_ptr<Data> &data);
|
||||
Q_SLOT void saveDatabaseData(const std::shared_ptr<Data> &data);
|
||||
Q_SLOT void areDataReady();
|
||||
|
||||
signals:
|
||||
@ -56,8 +54,8 @@ private:
|
||||
serversdk::DatabaseManager dbMan;
|
||||
Timestamp mlastSync;
|
||||
|
||||
std::shared_ptr<Data> colnodData;
|
||||
std::shared_ptr<Data> databaseData;
|
||||
// std::shared_ptr<Data> colnodData;
|
||||
// std::shared_ptr<Data> databaseData;
|
||||
|
||||
std::shared_ptr<Data> colnodDataToProcess;
|
||||
std::shared_ptr<Data> databaseDataToProcess;
|
||||
|
||||
@ -6,12 +6,37 @@
|
||||
class SyncManagerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
std::shared_ptr<Token> tokenFromString(const QString &text);
|
||||
private slots:
|
||||
void tokenFromString_test();
|
||||
void sync_init_test();
|
||||
void prepareData_test();
|
||||
void prepareData_tokens();
|
||||
void prepareData_tokens_data();
|
||||
|
||||
};
|
||||
|
||||
std::shared_ptr<Token> SyncManagerTest::tokenFromString(const QString &text)
|
||||
{
|
||||
auto split = text.split(",");
|
||||
if (split.count() != 2)
|
||||
return nullptr;
|
||||
|
||||
auto token = std::make_shared<Token>();
|
||||
token->setId(split.first());
|
||||
token->setDescription("mobile");
|
||||
token->setLastUpdate(QDateTime::fromString(split.last(), "yyyyMMdd:HHmmss"));
|
||||
return token;
|
||||
}
|
||||
|
||||
void SyncManagerTest::tokenFromString_test()
|
||||
{
|
||||
auto token = tokenFromString("id1,20191010:232300");
|
||||
QCOMPARE(token->id(), QStringLiteral("id1"));
|
||||
QCOMPARE(token->lastUpdate(), QDateTime::fromString("20191010:232300", "yyyyMMdd:HHmmss"));
|
||||
}
|
||||
|
||||
void SyncManagerTest::sync_init_test()
|
||||
{
|
||||
SyncManager sync(true);
|
||||
@ -22,14 +47,15 @@ void SyncManagerTest::sync_init_test()
|
||||
void SyncManagerTest::prepareData_test()
|
||||
{
|
||||
SyncManager sync(true);
|
||||
QVERIFY(sync.databaseInitialization());
|
||||
auto dbData = std::make_shared<Data>();
|
||||
auto colnodData = std::make_shared<Data>();
|
||||
|
||||
auto token = std::make_shared<Token>();
|
||||
token->setDescription("mobile");
|
||||
token->setId("id1");
|
||||
dbData->updatedTokens.insert("id1", token);
|
||||
|
||||
|
||||
auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData);
|
||||
auto newPreparedData = sync.prepareDataNew(dbData, colnodData);
|
||||
QVERIFY(oldPreparedData->databaseData->updatedTokens.contains("id1"));
|
||||
@ -42,6 +68,87 @@ void SyncManagerTest::prepareData_test()
|
||||
QVERIFY(newPreparedData->databaseData->deletedSubjects.isEmpty());
|
||||
}
|
||||
|
||||
void SyncManagerTest::prepareData_tokens()
|
||||
{
|
||||
SyncManager sync(true);
|
||||
QVERIFY(sync.databaseInitialization());
|
||||
|
||||
|
||||
|
||||
QFETCH(QString, db_token_updated);
|
||||
QFETCH(QString, db_token_deleted);
|
||||
QFETCH(QString, colnod_token_updated);
|
||||
QFETCH(QString, colnod_token_deleted);
|
||||
QFETCH(QString, expected_db_tokens_toupdate);
|
||||
QFETCH(QString, expected_db_tokens_todelete);
|
||||
QFETCH(QString, expected_colnod_tokens_toupdate);
|
||||
QFETCH(QString, expected_colnod_tokens_todelete);
|
||||
|
||||
// fake data
|
||||
auto dbData = std::make_shared<Data>();
|
||||
auto colnodData = std::make_shared<Data>();
|
||||
|
||||
// Database
|
||||
auto utoken = tokenFromString(db_token_updated);
|
||||
if ( utoken )
|
||||
dbData->updatedTokens.insert(utoken->id(), utoken);
|
||||
auto dtoken = tokenFromString(db_token_deleted);
|
||||
if ( dtoken )
|
||||
dbData->deletedTokens.append(dtoken->id());
|
||||
|
||||
// Colnod
|
||||
auto colnod_utoken = tokenFromString(colnod_token_updated);
|
||||
if ( colnod_utoken )
|
||||
colnodData->updatedTokens.insert(colnod_utoken->id(), colnod_utoken);
|
||||
auto colnod_dtoken = tokenFromString(colnod_token_deleted);
|
||||
if ( colnod_dtoken )
|
||||
colnodData->deletedTokens.append(colnod_dtoken->id());
|
||||
|
||||
auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData);
|
||||
auto newPreparedData = sync.prepareDataNew(dbData, colnodData);
|
||||
|
||||
QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate));
|
||||
QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete));
|
||||
QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate));
|
||||
QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete));
|
||||
|
||||
QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate));
|
||||
QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete));
|
||||
QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate));
|
||||
QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete));
|
||||
|
||||
}
|
||||
|
||||
void SyncManagerTest::prepareData_tokens_data()
|
||||
{
|
||||
QTest::addColumn<QString>("db_token_updated");
|
||||
QTest::addColumn<QString>("db_token_deleted");
|
||||
QTest::addColumn<QString>("colnod_token_updated");
|
||||
QTest::addColumn<QString>("colnod_token_deleted");
|
||||
QTest::addColumn<QString>("expected_db_tokens_toupdate");
|
||||
QTest::addColumn<QString>("expected_db_tokens_todelete");
|
||||
QTest::addColumn<QString>("expected_colnod_tokens_toupdate");
|
||||
QTest::addColumn<QString>("expected_colnod_tokens_todelete");
|
||||
|
||||
// in: db 1 new token
|
||||
// out: 1 db token must be updated in colnod
|
||||
QTest::newRow("db 1 update") << "id1,20191010:23:23:00" << ""
|
||||
<< "" << ""
|
||||
// expected database: toupdate << todelete
|
||||
<< "id1" << ""
|
||||
// expected colnod: toupdate << todelete
|
||||
<< "" << "";
|
||||
// in: id1 in database new/updated
|
||||
// in: id1 deleted in colnod
|
||||
// out: 1 colnod token must be deleted from database
|
||||
QTest::newRow("delete 1 existing token in database") << "id1,20191010:23:23:00" << ""
|
||||
<< "" << "id1,20191010:23:23:00"
|
||||
// expected database: toupdate << todelete
|
||||
<< "" << "id1"
|
||||
// expected colnod: toupdate << todelete
|
||||
<< "" << "";
|
||||
}
|
||||
|
||||
QTEST_MAIN(SyncManagerTest)
|
||||
|
||||
#include "tst_syncmanager.moc"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user