// Тест SyncManager: каталог ошибок, busy-счётчик, валидация параметров #include #include #include #include #include "sync/SyncManager.h" static int fail(const char *msg, const QString &detail = QString()) { std::fprintf(stderr, "FAIL: %s %s\n", msg, qPrintable(detail)); return 1; } struct Spy { int count=0; bool lastOk=false; int lastCode=0; QString lastTitle; void connectTo(SyncManager *sm){ QObject::connect(sm, &SyncManager::connectionResult, [this](int, bool ok, int code, const QString& t, const QString&, const QString&){ count++; lastOk=ok; lastCode=code; lastTitle=t; }); } void reset(){ count=0; lastOk=false; lastCode=0; lastTitle.clear(); } }; int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); SyncManager sm; // error catalog if (sm.errorTitle(SyncManager::Ok) != "OK") return fail("errorTitle Ok"); if (sm.errorTitle(SyncManager::Unauthorized).isEmpty()) return fail("errorTitle 401 empty"); if (sm.errorHint(SyncManager::Unauthorized).isEmpty()) return fail("errorHint 401 empty"); if (sm.errorHint(SyncManager::Timeout).isEmpty()) return fail("hint timeout"); if (!sm.errorTitle(999).contains("999")) return fail("unknown error title"); // busy initial if (sm.busy()) return fail("initial busy should be false"); // testConnection with empty token should immediately finish with Unauthorized without network { Spy spy; spy.connectTo(&sm); sm.testConnection(SyncManager::GitHub, "https://api.github.com", "", ""); // need to process events for direct connection? finish emits synchronously, but signal is direct, so count should be 1 immediately // However finish is synchronous, so after call count should be 1 if (spy.count != 1) return fail("empty token spy count", QString::number(spy.count)); if (spy.lastOk) return fail("empty token should not ok"); if (spy.lastCode != SyncManager::Unauthorized) return fail("empty token code", QString::number(spy.lastCode)); if (sm.busy()) return fail("busy after empty token"); } // Need new manager for isolated spy because previous connection stays { SyncManager sm2; Spy spy; spy.connectTo(&sm2); sm2.testConnection(99, "https://example.com", "", "token123"); if (spy.count!=1) return fail("invalid provider spy", QString::number(spy.count)); if (spy.lastCode != SyncManager::NetworkError) return fail("invalid provider code", QString::number(spy.lastCode)); } // invalid URL for WebDAV { SyncManager sm2; Spy spy; spy.connectTo(&sm2); sm2.testConnection(SyncManager::WebDav, "not-a-url", "user", "pass"); if (spy.count!=1) return fail("webdav invalid url spy count", QString::number(spy.count)); if (spy.lastCode != SyncManager::NetworkError) return fail("webdav invalid url code", QString::number(spy.lastCode)); } // Check busy counter with actual network request (will timeout or fail, but busy should be managed) { SyncManager sm2; int busyChangedCount=0; QObject::connect(&sm2, &SyncManager::busyChanged, [&](){ busyChangedCount++; }); sm2.testConnection(SyncManager::Syncthing, "http://127.0.0.1:1", "", "fake"); if (!sm2.busy()) return fail("busy should be true after request"); QEventLoop loop; QTimer timer; timer.setSingleShot(true); QObject::connect(&sm2, &SyncManager::connectionResult, &loop, &QEventLoop::quit); QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); timer.start(3000); loop.exec(); if (sm2.busy()) return fail("busy should be false after reply"); if (busyChangedCount < 1) return fail("busyChanged not emitted"); } // Test busy counter with two parallel requests { SyncManager sm2; sm2.testConnection(SyncManager::GitHub, "https://api.github.com", "", "tok1"); sm2.testConnection(SyncManager::GitLab, "https://gitlab.com", "", "tok2"); if (!sm2.busy()) return fail("busy after two requests"); QEventLoop loop; int count = 0; QObject::connect(&sm2, &SyncManager::connectionResult, &loop, [&](int, bool, int, const QString&, const QString&, const QString&){ count++; if (count>=2) loop.quit(); }); QTimer::singleShot(4000, &loop, &QEventLoop::quit); loop.exec(); QEventLoop loop2; QTimer::singleShot(1000, &loop2, &QEventLoop::quit); loop2.exec(); if (count==0) return fail("no parallel results"); } std::printf("SYNC TEST OK\n"); return 0; }