From 1994114975f1bac5959e925ea225c51e0e8d610a Mon Sep 17 00:00:00 2001 From: VitorVieiraZ Date: Fri, 8 Nov 2024 00:13:40 -0300 Subject: [PATCH] test adjustment --- app/test/testmerginapi.cpp | 70 ++++++++++++++++++++------------------ app/test/testmerginapi.h | 47 ++++++++++++++++--------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/app/test/testmerginapi.cpp b/app/test/testmerginapi.cpp index f083bec50..bc32dc807 100644 --- a/app/test/testmerginapi.cpp +++ b/app/test/testmerginapi.cpp @@ -2945,53 +2945,57 @@ void TestMerginApi::testParseVersion() void TestMerginApi::testDownloadWithNetworkError() { - // Store original network manager to restore it later - QNetworkAccessManager *originalManager = mApi->networkManager(); + QString projectName = "testDownloadRetry"; - // create a project and do initial setup - QString projectName = "testDownloadWithNetworkError"; + // create the project on the server (the content is not important) createRemoteProject( mApiExtra, mWorkspaceName, projectName, mTestDataPath + "/" + TEST_PROJECT_NAME + "/" ); - // Set up mock network manager that will fail after first chunk - MockNetworkManager *mockManager = new MockNetworkManager(); + // Create mock manager - initially not failing + MockNetworkManager *mockManager = new MockNetworkManager( this ); mApi->setNetworkManager( mockManager ); - QSignalSpy spyDownloadStarted( mApi, &MerginApi::downloadItemsStarted ); - QSignalSpy spyRetried( mApi, &MerginApi::downloadItemRetried ); - QSignalSpy spyFinished( mApi, &MerginApi::syncProjectFinished ); + // Create signal spies + QSignalSpy startSpy( mApi, &MerginApi::downloadItemsStarted ); + QSignalSpy retrySpy( mApi, &MerginApi::downloadItemRetried ); + QSignalSpy finishSpy( mApi, &MerginApi::syncProjectFinished ); - // Start download - mApi->pullProject( mWorkspaceName, projectName ); + // Connect to downloadItemsStarted to trigger failure when items download start + connect( mApi, &MerginApi::downloadItemsStarted, this, [this]() + { + MockNetworkManager *failingManager = new MockNetworkManager( this ); + failingManager->setShouldFail( true ); + mApi->setNetworkManager( failingManager ); + } ); - // Wait for individual downloads to start - QVERIFY( spyDownloadStarted.wait( TestUtils::SHORT_REPLY ) ); - QCOMPARE( spyDownloadStarted.count(), 1 ); + // Try to download the project + mApi->pullProject( mWorkspaceName, projectName ); - // Now simulate network failure - mockManager->setShouldFail( true ); + // Verify a transaction was created + QCOMPARE( mApi->transactions().count(), 1 ); - // Wait for retries - QVERIFY( spyRetried.wait( TestUtils::LONG_REPLY ) ); - QVERIFY( spyRetried.count() >= 1 ); // Should have at least one retry + // Wait for the download to start and then fail + QVERIFY( startSpy.wait( TestUtils::LONG_REPLY ) ); + QVERIFY( finishSpy.wait( TestUtils::LONG_REPLY ) ); - QList retryArgs = spyRetried.takeFirst(); - QCOMPARE( retryArgs.at( 0 ).toString(), MerginApi::getFullProjectName( mWorkspaceName, projectName ) ); - QVERIFY( retryArgs.at( 1 ).toInt() >= 1 ); + // Verify signals were emitted + QVERIFY( startSpy.count() > 0 ); + QVERIFY( retrySpy.count() > 0 ); + QCOMPARE( finishSpy.count(), 1 ); - // Restore normal network behavior to let download finish - mockManager->setShouldFail( false ); + // Verify that 5 (MAX_RETRY_COUNT) retry attempts were made + int maxRetries = TransactionStatus::MAX_RETRY_COUNT; + QCOMPARE( retrySpy.count(), maxRetries ); - // Wait for download to finish - QVERIFY( spyFinished.wait( TestUtils::LONG_REPLY ) ); - QCOMPARE( spyFinished.count(), 1 ); + // Verify the sync failed + QList arguments = finishSpy.takeFirst(); + QVERIFY( !arguments.at( 1 ).toBool() ); - QList finishArgs = spyFinished.takeFirst(); - QCOMPARE( finishArgs.at( 0 ).toString(), MerginApi::getFullProjectName( mWorkspaceName, projectName ) ); - QVERIFY( finishArgs.at( 1 ).toBool() ); // Should finish successfully + // Verify no local project was created + LocalProject localProject = mApi->localProjectsManager().projectFromMerginName( mWorkspaceName, projectName ); + QVERIFY( !localProject.isValid() ); - // Clean up and restore original network manager - deleteLocalProject( mApi, mWorkspaceName, projectName ); + // Restore the original manager + QNetworkAccessManager *originalManager = new QNetworkAccessManager( this ); mApi->setNetworkManager( originalManager ); - delete mockManager; } diff --git a/app/test/testmerginapi.h b/app/test/testmerginapi.h index d7b299906..929f20ca2 100644 --- a/app/test/testmerginapi.h +++ b/app/test/testmerginapi.h @@ -24,15 +24,32 @@ class MockReply : public QNetworkReply { public: - explicit MockReply( QObject *parent = nullptr ) : QNetworkReply( parent ) + explicit MockReply( const QNetworkRequest &request, QNetworkAccessManager::Operation operation, QObject *parent = nullptr ) + : QNetworkReply( parent ) { - QNetworkReply::setError( QNetworkReply::TimeoutError, "Mock network failure" ); + setRequest( request ); + setOperation( operation ); + setUrl( request.url() ); + + setError( QNetworkReply::TimeoutError, "Mock network failure" ); + + QMetaObject::invokeMethod( this, "errorOccurred", Qt::QueuedConnection, Q_ARG( QNetworkReply::NetworkError, QNetworkReply::TimeoutError ) ); QMetaObject::invokeMethod( this, "finished", Qt::QueuedConnection ); } void abort() override {} - qint64 readData( char *, qint64 ) override { return -1; } - qint64 writeData( const char *, qint64 ) override { return -1; } + + qint64 readData( char *data, qint64 maxlen ) override + { + Q_UNUSED( data ); + Q_UNUSED( maxlen ); + return -1; + } + + qint64 bytesAvailable() const override + { + return 0; + } }; class MockNetworkManager : public QNetworkAccessManager @@ -43,25 +60,23 @@ class MockNetworkManager : public QNetworkAccessManager , mShouldFail( false ) {} - void setShouldFail( bool shouldFail ) { mShouldFail = shouldFail; } - bool shouldFail() const { return mShouldFail; } - - QNetworkReply *get( const QNetworkRequest &request ) + void setShouldFail( bool shouldFail ) { - if ( mShouldFail ) - { - return new MockReply( this ); - } - return QNetworkAccessManager::get( request ); + mShouldFail = shouldFail; } - QNetworkReply *post( const QNetworkRequest &request, const QByteArray &data ) + bool shouldFail() const { return mShouldFail; } + + protected: + QNetworkReply *createRequest( Operation op, const QNetworkRequest &request, QIODevice *outgoingData = nullptr ) override { if ( mShouldFail ) { - return new MockReply( this ); + MockReply *reply = new MockReply( request, op, this ); + return reply; } - return QNetworkAccessManager::post( request, data ); + + return QNetworkAccessManager::createRequest( op, request, outgoingData ); } private: