2021-12-23 13:57:08 +03:00
/*
* Copyright ( C ) by Claudio Cambra < claudio . cambra @ nextcloud . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* for more details .
*/
2023-03-01 01:50:49 +03:00
# include "activitylistmodeltestutils.h"
2021-12-23 13:57:08 +03:00
# include "syncenginetestutils.h"
# include "syncresult.h"
# include <QAbstractItemModelTester>
# include <QDesktopServices>
# include <QSignalSpy>
# include <QTest>
2023-03-01 03:52:22 +03:00
using namespace ActivityListModelTestUtils ;
2021-12-23 13:57:08 +03:00
class TestActivityListModel : public QObject
{
Q_OBJECT
public :
TestActivityListModel ( ) = default ;
2022-07-13 21:11:37 +03:00
~ TestActivityListModel ( ) override
{
2021-12-23 13:57:08 +03:00
OCC : : AccountManager : : instance ( ) - > deleteAccount ( accountState . data ( ) ) ;
}
QScopedPointer < FakeQNAM > fakeQnam ;
OCC : : AccountPtr account ;
QScopedPointer < OCC : : AccountState > accountState ;
OCC : : Activity testNotificationActivity ;
2022-07-13 21:11:37 +03:00
OCC : : Activity testSyncResultErrorActivity ;
OCC : : Activity testSyncFileItemActivity ;
OCC : : Activity testFileIgnoredActivity ;
2021-12-23 13:57:08 +03:00
static constexpr int searchResultsReplyDelay = 100 ;
2022-07-13 21:11:37 +03:00
QSharedPointer < TestingALM > testingALM ( ) {
QSharedPointer < TestingALM > model ( new TestingALM ) ;
model - > setAccountState ( accountState . data ( ) ) ;
QAbstractItemModelTester modelTester ( model . data ( ) ) ;
return model ;
}
2022-10-12 12:19:00 +03:00
void testActivityAdd ( void ( OCC : : ActivityListModel : : * addingMethod ) ( const OCC : : Activity & , OCC : : ActivityListModel : : ErrorType ) , OCC : : Activity & activity ) {
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
( model . data ( ) - > * addingMethod ) ( activity , OCC : : ActivityListModel : : ErrorType : : SyncError ) ;
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
const auto index = model - > index ( 0 , 0 ) ;
QVERIFY ( index . isValid ( ) ) ;
}
2022-07-13 21:11:37 +03:00
void testActivityAdd ( void ( OCC : : ActivityListModel : : * addingMethod ) ( const OCC : : Activity & ) , OCC : : Activity & activity ) {
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
( model . data ( ) - > * addingMethod ) ( activity ) ;
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
const auto index = model - > index ( 0 , 0 ) ;
QVERIFY ( index . isValid ( ) ) ;
}
2022-10-11 17:10:53 +03:00
void testActivityAdd ( void ( OCC : : ActivityListModel : : * addingMethod ) ( const OCC : : Activity & , OCC : : ActivityListModel : : ErrorType ) , OCC : : Activity & activity , OCC : : ActivityListModel : : ErrorType type ) {
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
( model . data ( ) - > * addingMethod ) ( activity , type ) ;
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
const auto index = model - > index ( 0 , 0 ) ;
QVERIFY ( index . isValid ( ) ) ;
}
2021-12-23 13:57:08 +03:00
private slots :
void initTestCase ( )
{
fakeQnam . reset ( new FakeQNAM ( { } ) ) ;
account = OCC : : Account : : create ( ) ;
account - > setCredentials ( new FakeCredentials { fakeQnam . data ( ) } ) ;
account - > setUrl ( QUrl ( ( " http://example.de " ) ) ) ;
accountState . reset ( new OCC : : AccountState ( account ) ) ;
fakeQnam - > setOverride ( [ this ] ( QNetworkAccessManager : : Operation op , const QNetworkRequest & req , QIODevice * device ) {
2023-03-01 03:52:22 +03:00
Q_UNUSED ( device )
return almTestQnamOverride ( fakeQnam . data ( ) ,
op ,
req ,
accountState - > account ( ) - > url ( ) . toString ( ) ,
this ,
searchResultsReplyDelay ) ;
2021-12-23 13:57:08 +03:00
} ) ;
OCC : : AccountManager : : instance ( ) - > addAccount ( account ) ;
2023-03-01 04:06:24 +03:00
const auto accName = accountState - > account ( ) - > displayName ( ) ;
const auto accUrl = accountState - > account ( ) - > url ( ) ;
testNotificationActivity = exampleNotificationActivity ( accName ) ;
testSyncResultErrorActivity = exampleSyncResultErrorActivity ( accName ) ;
testSyncFileItemActivity = exampleSyncFileItemActivity ( accName , accUrl ) ;
testFileIgnoredActivity = exampleFileIgnoredActivity ( accName , accUrl ) ;
2021-12-23 13:57:08 +03:00
} ;
// Test receiving activity from server
void testFetchingRemoteActivity ( ) {
2022-07-13 21:11:37 +03:00
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
model - > setCurrentItem ( FakeRemoteActivityStorage : : instance ( ) - > startingIdLast ( ) ) ;
model - > startFetchJob ( ) ;
QSignalSpy activitiesJob ( model . data ( ) , & TestingALM : : activitiesProcessed ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( activitiesJob . wait ( 3000 ) ) ;
2022-07-13 21:11:37 +03:00
QCOMPARE ( model - > rowCount ( ) , 50 ) ;
2021-12-23 13:57:08 +03:00
} ;
// Test receiving activity from local user action
void testLocalSyncFileAction ( ) {
2022-07-13 21:11:37 +03:00
testActivityAdd ( & TestingALM : : addSyncFileItemToActivityList , testSyncFileItemActivity ) ;
2021-12-23 13:57:08 +03:00
} ;
void testAddNotification ( ) {
2022-07-13 21:11:37 +03:00
testActivityAdd ( & TestingALM : : addNotificationToActivityList , testNotificationActivity ) ;
2021-12-23 13:57:08 +03:00
} ;
void testAddError ( ) {
2022-10-11 17:10:53 +03:00
testActivityAdd ( & TestingALM : : addErrorToActivityList , testSyncResultErrorActivity , OCC : : ActivityListModel : : ErrorType : : SyncError ) ;
2021-12-23 13:57:08 +03:00
} ;
void testAddIgnoredFile ( ) {
2022-07-13 21:11:37 +03:00
testActivityAdd ( & TestingALM : : addIgnoredFileToList , testFileIgnoredActivity ) ;
2021-12-23 13:57:08 +03:00
} ;
// Test removing activity from list
void testRemoveActivityWithRow ( ) {
2022-07-13 21:11:37 +03:00
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
model - > addNotificationToActivityList ( testNotificationActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
model - > removeActivityFromActivityList ( 0 ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
2021-12-23 13:57:08 +03:00
}
void testRemoveActivityWithActivity ( ) {
2022-07-13 21:11:37 +03:00
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
model - > addNotificationToActivityList ( testNotificationActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
model - > removeActivityFromActivityList ( testNotificationActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
}
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
void testDummyFetchingActivitiesActivity ( ) {
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
model - > setCurrentItem ( FakeRemoteActivityStorage : : instance ( ) - > startingIdLast ( ) ) ;
model - > startFetchJob ( ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
// Check for the dummy before activities have arrived
QCOMPARE ( model - > rowCount ( ) , 1 ) ;
QSignalSpy activitiesJob ( model . data ( ) , & TestingALM : : activitiesProcessed ) ;
QVERIFY ( activitiesJob . wait ( 3000 ) ) ;
// Test the dummy was removed
QCOMPARE ( model - > rowCount ( ) , 50 ) ;
2021-12-23 13:57:08 +03:00
}
// Test getting the data from the model
void testData ( ) {
2022-07-13 21:11:37 +03:00
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
2021-12-23 13:57:08 +03:00
2022-07-13 21:11:37 +03:00
model - > setCurrentItem ( FakeRemoteActivityStorage : : instance ( ) - > startingIdLast ( ) ) ;
model - > startFetchJob ( ) ;
QSignalSpy activitiesJob ( model . data ( ) , & TestingALM : : activitiesProcessed ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( activitiesJob . wait ( 3000 ) ) ;
2022-07-13 21:11:37 +03:00
QCOMPARE ( model - > rowCount ( ) , 50 ) ;
model - > addSyncFileItemToActivityList ( testSyncFileItemActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 51 ) ;
2022-10-11 17:10:53 +03:00
model - > addErrorToActivityList ( testSyncResultErrorActivity , OCC : : ActivityListModel : : ErrorType : : SyncError ) ;
2022-07-13 21:11:37 +03:00
QCOMPARE ( model - > rowCount ( ) , 52 ) ;
model - > addIgnoredFileToList ( testFileIgnoredActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 53 ) ;
model - > addNotificationToActivityList ( testNotificationActivity ) ;
QCOMPARE ( model - > rowCount ( ) , 54 ) ;
2021-12-23 13:57:08 +03:00
// Test all rows for things in common
2022-07-13 21:11:37 +03:00
for ( int i = 0 ; i < model - > rowCount ( ) ; i + + ) {
const auto index = model - > index ( i , 0 ) ;
2022-01-04 17:28:26 +03:00
auto text = index . data ( OCC : : ActivityListModel : : ActionTextRole ) . toString ( ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : ActionRole ) . canConvert < int > ( ) ) ;
const auto type = index . data ( OCC : : ActivityListModel : : ActionRole ) . toInt ( ) ;
2022-09-14 03:26:38 +03:00
QVERIFY ( type > = OCC : : Activity : : DummyFetchingActivityType ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( ! index . data ( OCC : : ActivityListModel : : AccountRole ) . toString ( ) . isEmpty ( ) ) ;
QVERIFY ( ! index . data ( OCC : : ActivityListModel : : ActionTextColorRole ) . toString ( ) . isEmpty ( ) ) ;
2022-03-21 19:34:21 +03:00
QVERIFY ( ! index . data ( OCC : : ActivityListModel : : DarkIconRole ) . toString ( ) . isEmpty ( ) ) ;
QVERIFY ( ! index . data ( OCC : : ActivityListModel : : LightIconRole ) . toString ( ) . isEmpty ( ) ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( ! index . data ( OCC : : ActivityListModel : : PointInTimeRole ) . toString ( ) . isEmpty ( ) ) ;
2022-03-05 15:44:03 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : ObjectTypeRole ) . canConvert < int > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : ObjectNameRole ) . canConvert < QString > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : ObjectIdRole ) . canConvert < int > ( ) ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : ActionsLinksRole ) . canConvert < QList < QVariant > > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : ActionTextRole ) . canConvert < QString > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : MessageRole ) . canConvert < QString > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : LinkRole ) . canConvert < QUrl > ( ) ) ;
2023-05-12 17:46:23 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : ActionsLinksForActionButtonsRole ) . canConvert < QList < QVariant > > ( ) ) ;
2021-12-23 13:57:08 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : AccountConnectedRole ) . canConvert < bool > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : DisplayActions ) . canConvert < bool > ( ) ) ;
2022-04-05 19:44:35 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : TalkNotificationConversationTokenRole ) . canConvert < QString > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : TalkNotificationMessageIdRole ) . canConvert < QString > ( ) ) ;
QVERIFY ( index . data ( OCC : : ActivityListModel : : TalkNotificationMessageSentRole ) . canConvert < QString > ( ) ) ;
2022-09-14 03:26:38 +03:00
QVERIFY ( index . data ( OCC : : ActivityListModel : : ActivityRole ) . canConvert < OCC : : Activity > ( ) ) ;
2021-12-23 13:57:08 +03:00
// Unfortunately, trying to check anything relating to filepaths causes a crash
// when the folder manager is invoked by the model to look for the relevant file
}
} ;
2022-07-13 21:11:37 +03:00
void testActivityActionsData ( )
2022-01-04 17:28:26 +03:00
{
2022-07-13 21:11:37 +03:00
const auto model = testingALM ( ) ;
QCOMPARE ( model - > rowCount ( ) , 0 ) ;
model - > setCurrentItem ( FakeRemoteActivityStorage : : instance ( ) - > startingIdLast ( ) ) ;
2022-01-04 17:28:26 +03:00
2022-07-13 21:11:37 +03:00
int prevModelRowCount = model - > rowCount ( ) ;
2022-01-04 17:28:26 +03:00
do {
2022-07-13 21:11:37 +03:00
prevModelRowCount = model - > rowCount ( ) ;
model - > startFetchJob ( ) ;
QSignalSpy activitiesJob ( model . data ( ) , & TestingALM : : activitiesProcessed ) ;
2022-01-04 17:28:26 +03:00
QVERIFY ( activitiesJob . wait ( 3000 ) ) ;
2022-07-13 21:11:37 +03:00
for ( int i = prevModelRowCount ; i < model - > rowCount ( ) ; i + + ) {
const auto index = model - > index ( i , 0 ) ;
2022-01-04 17:28:26 +03:00
const auto actionsLinks = index . data ( OCC : : ActivityListModel : : ActionsLinksRole ) . toList ( ) ;
if ( ! actionsLinks . isEmpty ( ) ) {
2023-08-03 10:00:55 +03:00
const auto actionsLinksContextMenu = index . data ( OCC : : ActivityListModel : : ActionsLinksContextMenuRole ) . toList ( ) ;
2022-01-04 17:28:26 +03:00
// context menu must be shorter than total action links
2022-09-29 18:15:50 +03:00
QVERIFY ( actionsLinksContextMenu . isEmpty ( ) | | actionsLinksContextMenu . size ( ) < actionsLinks . size ( ) ) ;
2022-01-04 17:28:26 +03:00
// context menu must not contain the primary action
QVERIFY ( std : : find_if ( std : : begin ( actionsLinksContextMenu ) , std : : end ( actionsLinksContextMenu ) ,
[ ] ( const QVariant & entry ) { return entry . value < OCC : : ActivityLink > ( ) . _primary ; } )
= = std : : end ( actionsLinksContextMenu ) ) ;
const auto objectType = index . data ( OCC : : ActivityListModel : : ObjectTypeRole ) . toString ( ) ;
2023-08-03 10:00:55 +03:00
const auto actionButtonsLinks = index . data ( OCC : : ActivityListModel : : ActionsLinksForActionButtonsRole ) . toList ( ) ;
2022-09-30 16:45:53 +03:00
// Login attempt notification
if ( objectType = = QStringLiteral ( " 2fa_id " ) ) {
QVERIFY ( actionsLinks . size ( ) = = 2 ) ;
QVERIFY ( actionsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _primary ) ;
QVERIFY ( ! actionsLinks [ 1 ] . value < OCC : : ActivityLink > ( ) . _primary ) ;
QVERIFY ( actionsLinksContextMenu . isEmpty ( ) ) ;
}
2023-05-12 17:46:23 +03:00
// Generate 2FA backup codes notification
if ( objectType = = QStringLiteral ( " create " ) ) {
QVERIFY ( actionsLinks . size ( ) = = 1 ) ;
QVERIFY ( ! actionsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _primary ) ;
QVERIFY ( actionsLinksContextMenu . isEmpty ( ) ) ;
}
2024-03-04 16:00:20 +03:00
// remote shares must have 'Accept' and 'Decline' actions
if ( objectType = = QStringLiteral ( " remote_share " ) ) {
QVERIFY ( actionsLinks . size ( ) = = 2 ) ;
QVERIFY ( actionsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _primary ) ;
QVERIFY ( actionsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _verb = = QStringLiteral ( " POST " ) ) ;
QVERIFY ( actionsLinks [ 1 ] . value < OCC : : ActivityLink > ( ) . _verb = = QStringLiteral ( " DELETE " ) ) ;
}
2022-01-04 17:28:26 +03:00
if ( ( objectType = = QStringLiteral ( " chat " ) | | objectType = = QStringLiteral ( " call " )
| | objectType = = QStringLiteral ( " room " ) ) ) {
2022-09-29 18:15:50 +03:00
auto replyActionPos = 0 ;
if ( objectType = = QStringLiteral ( " call " ) ) {
replyActionPos = 1 ;
}
// both action links and buttons must contain a "REPLY" verb element as secondary action
QVERIFY ( actionsLinks [ replyActionPos ] . value < OCC : : ActivityLink > ( ) . _verb = = QStringLiteral ( " REPLY " ) ) ;
2023-05-17 16:31:47 +03:00
//QVERIFY(actionButtonsLinks[replyActionPos].value<OCC::ActivityLink>()._verb == QStringLiteral("REPLY"));
2022-04-05 19:44:35 +03:00
2022-01-04 17:28:26 +03:00
// the first action button for chat must have image set
2023-05-17 16:31:47 +03:00
//QVERIFY(!actionButtonsLinks[replyActionPos].value<OCC::ActivityLink>()._imageSource.isEmpty());
//QVERIFY(!actionButtonsLinks[replyActionPos].value<OCC::ActivityLink>()._imageSourceHovered.isEmpty());
2022-01-04 17:28:26 +03:00
// logic for "chat" and other types of activities with multiple actions
if ( ( objectType = = QStringLiteral ( " chat " )
| | ( objectType ! = QStringLiteral ( " room " ) & & objectType ! = QStringLiteral ( " call " ) ) ) ) {
// button's label for "chat" must be renamed to "Reply"
QVERIFY ( actionButtonsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _label = = QObject : : tr ( " Reply " ) ) ;
if ( static_cast < quint32 > ( actionsLinks . size ( ) ) > OCC : : ActivityListModel : : maxActionButtons ( ) ) {
2023-08-03 10:00:55 +03:00
QCOMPARE ( actionButtonsLinks . size ( ) , OCC : : ActivityListModel : : maxActionButtons ( ) ) ;
2022-01-04 17:28:26 +03:00
// in case total actions is longer than ActivityListModel::maxActionButtons, then a sum of action buttons and action menu entries must be equal to a total of action links
2023-08-03 10:00:55 +03:00
QCOMPARE ( actionButtonsLinks . size ( ) + actionsLinksContextMenu . size ( ) , actionsLinks . size ( ) ) ;
2022-01-04 17:28:26 +03:00
}
} else if ( ( objectType = = QStringLiteral ( " call " ) ) ) {
2023-08-03 10:00:55 +03:00
QVERIFY ( actionButtonsLinks [ 0 ] . value < OCC : : ActivityLink > ( ) . _label = = QStringLiteral ( " Call back " ) ) ;
2022-01-04 17:28:26 +03:00
}
}
}
}
2022-07-13 21:11:37 +03:00
} while ( prevModelRowCount < model - > rowCount ( ) ) ;
2022-01-04 17:28:26 +03:00
} ;
2021-12-23 13:57:08 +03:00
} ;
QTEST_MAIN ( TestActivityListModel )
# include "testactivitylistmodel.moc"