Skip to content

Commit

Permalink
test adjustment
Browse files Browse the repository at this point in the history
  • Loading branch information
VitorVieiraZ committed Nov 8, 2024
1 parent 9e029b1 commit 1994114
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 49 deletions.
70 changes: 37 additions & 33 deletions app/test/testmerginapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<QVariant> 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<QVariant> arguments = finishSpy.takeFirst();
QVERIFY( !arguments.at( 1 ).toBool() );

QList<QVariant> 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;
}

47 changes: 31 additions & 16 deletions app/test/testmerginapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down

1 comment on commit 1994114

@inputapp-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS - version 24.11.693111 just submitted!

Please sign in to comment.