77
88#include " account.h"
99#include " accountstate.h"
10+ #include " folderman.h"
1011#include " syncenginetestutils.h"
12+ #include " testhelper.h"
1113
1214#include < QAbstractItemModelTester>
1315#include < QDesktopServices>
@@ -30,7 +32,8 @@ class FakeDesktopServicesUrlHandler : public QObject
3032
3133public:
3234signals:
33- void resultClicked (const QUrl &url);
35+ void resultClickedBrowser (const QUrl &url);
36+ void resultClickedLocalFile (const QUrl &url);
3437};
3538
3639/* *
@@ -278,6 +281,8 @@ class TestUnifiedSearchListModel : public QObject
278281{
279282 Q_OBJECT
280283
284+ std::unique_ptr<OCC::FolderMan> _folderMan;
285+
281286public:
282287 TestUnifiedSearchListModel () = default ;
283288
@@ -305,6 +310,7 @@ private slots:
305310 account->setUrl (QUrl ((" http://example.de" )));
306311
307312 accountState.reset (new OCC::AccountState (account));
313+ _folderMan.reset (new OCC::FolderMan{});
308314
309315 fakeQnam->setOverride ([this ](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device) {
310316 Q_UNUSED (device);
@@ -538,71 +544,173 @@ private slots:
538544 }
539545 }
540546
541- void testSearchResultlicked ()
547+ void testSearchResultClicked ()
542548 {
543- // make sure the model is empty
544- model->setSearchTerm (QStringLiteral (" " ));
545- QVERIFY (model->rowCount () == 0 );
546-
547- // test that search term gets set, search gets started and enough results get returned
548- model->setSearchTerm (model->searchTerm () + QStringLiteral (" discuss" ));
549-
550- QSignalSpy searchInProgressChanged (
551- model.data (), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged);
552-
553- QVERIFY (searchInProgressChanged.wait ());
554-
555- // make sure search has started
556- QCOMPARE (searchInProgressChanged.count (), 1 );
557- QVERIFY (model->isSearchInProgress ());
558-
559- QVERIFY (searchInProgressChanged.wait ());
560-
561- // make sure search has finished and some results has been received
562- QVERIFY (!model->isSearchInProgress ());
563-
564- QVERIFY (model->rowCount () != 0 );
565-
566- QDesktopServices::setUrlHandler (" http" , fakeDesktopServicesUrlHandler.data (), " resultClicked" );
567- QDesktopServices::setUrlHandler (" https" , fakeDesktopServicesUrlHandler.data (), " resultClicked" );
568-
569- QSignalSpy resultClicked (fakeDesktopServicesUrlHandler.data (), &FakeDesktopServicesUrlHandler::resultClicked);
570-
571- // test click on a result item
572- QString urlForClickedResult;
573-
574- for (int i = 0 ; i < model->rowCount (); ++i) {
575- const auto type = model->data (model->index (i), OCC::UnifiedSearchResultsListModel::DataRole::TypeRole);
576-
577- if (type == OCC::UnifiedSearchResult::Type::Default) {
578- const auto providerId =
579- model->data (model->index (i), OCC::UnifiedSearchResultsListModel::DataRole::ProviderIdRole)
580- .toString ();
581-
582- const auto subline =
583- model->data (model->index (i), OCC::UnifiedSearchResultsListModel::DataRole::SublineRole)
584- .toString ();
585-
586- const auto title =
587- model->data (model->index (i), OCC::UnifiedSearchResultsListModel::DataRole::TitleRole)
588- .toString ();
589-
590- urlForClickedResult = model->data (model->index (i), OCC::UnifiedSearchResultsListModel::DataRole::ResourceUrlRole).toString ();
591-
592- if (!providerId.isEmpty () && !urlForClickedResult.isEmpty ()) {
593- model->resultClicked (providerId, QUrl (urlForClickedResult), subline, title);
594- break ;
595- }
596- }
597- }
598-
599- QCOMPARE (resultClicked.count (), 1 );
600-
601- const auto arguments = resultClicked.takeFirst ();
602-
603- const auto urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
604-
605- QCOMPARE (urlOpenTriggeredViaDesktopServices, urlForClickedResult);
549+ QDesktopServices::setUrlHandler (" http" , fakeDesktopServicesUrlHandler.data (), " resultClickedBrowser" );
550+ QDesktopServices::setUrlHandler (" https" , fakeDesktopServicesUrlHandler.data (), " resultClickedBrowser" );
551+ QDesktopServices::setUrlHandler (" file" , fakeDesktopServicesUrlHandler.data (), " resultClickedLocalFile" );
552+
553+ QSignalSpy resultClickedBrowser (fakeDesktopServicesUrlHandler.data (), &FakeDesktopServicesUrlHandler::resultClickedBrowser);
554+ QSignalSpy resultClickedLocalFile (fakeDesktopServicesUrlHandler.data (), &FakeDesktopServicesUrlHandler::resultClickedLocalFile);
555+
556+ // Setup folder structure for further tests
557+ FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12 ()};
558+ const auto localFolderPrefix = " file:///" + fakeFolder.localPath ();
559+ auto folderDef = folderDefinition (fakeFolder.localPath ());
560+ folderDef.targetPath = " " ;
561+ const auto folder = OCC::FolderMan::instance ()->addFolder (accountState.data (), folderDef);
562+ QVERIFY (folder);
563+
564+ // Provider IDs which are not files, will be opened in the browser
565+ const auto providerIdTestProviderId = " settings_apps" ;
566+ const auto sublineTestProviderId = " John Doe in Apps" ;
567+ const auto titleTestProviderId = " We had a discussion about Apps already. But, let's have a follow up tomorrow afternoon." ;
568+ const auto resourceUrlTestProviderId = " http://example.de/call/abcde12345#message_12345" ;
569+ model->resultClicked (providerIdTestProviderId,
570+ QUrl (resourceUrlTestProviderId), sublineTestProviderId, titleTestProviderId);
571+
572+ QCOMPARE (resultClickedBrowser.count (), 1 );
573+ QCOMPARE (resultClickedLocalFile.count (), 0 );
574+
575+ auto arguments = resultClickedBrowser.takeFirst ();
576+ auto urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
577+ QCOMPARE (urlOpenTriggeredViaDesktopServices, resourceUrlTestProviderId);
578+
579+ resultClickedBrowser.clear ();
580+ resultClickedLocalFile.clear ();
581+
582+ // Nextcloud 20 opens in browser if the folder is not available locally
583+ const auto providerIdTestNextcloud20Browser = " file" ;
584+ const auto sublineTestNextcloud20Browser = " in folder/nested/searched_file.cpp" ;
585+ const auto titleTestNextcloud20Browser = " searched_file.cpp" ;
586+ const auto resourceUrlTestNextcloud20Browser = " http://example.de/files/?dir=folder/nested&scrollto=searched_file.cpp" ;
587+ model->resultClicked (providerIdTestNextcloud20Browser,
588+ QUrl (resourceUrlTestNextcloud20Browser), sublineTestNextcloud20Browser, titleTestNextcloud20Browser);
589+
590+ QCOMPARE (resultClickedBrowser.count (), 1 );
591+ QCOMPARE (resultClickedLocalFile.count (), 0 );
592+
593+ arguments = resultClickedBrowser.takeFirst ();
594+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
595+ QCOMPARE (urlOpenTriggeredViaDesktopServices, resourceUrlTestNextcloud20Browser);
596+
597+ resultClickedBrowser.clear ();
598+ resultClickedLocalFile.clear ();
599+
600+ // Nextcloud versions above 20 opens in browser if the folder is not available locally
601+ const auto providerIdTestNextcloudAbove20Browser = " file" ;
602+ const auto sublineTestNextcloudAbove20Browser = " in folder/nested" ;
603+ const auto titleTestNextcloudAbove20Browser = " searched_file.cpp" ;
604+ const auto resourceUrlTestNextcloudAbove20Browser = " http://example.de/index.php/f/123" ;
605+ model->resultClicked (providerIdTestNextcloudAbove20Browser,
606+ QUrl (resourceUrlTestNextcloudAbove20Browser), sublineTestNextcloudAbove20Browser,
607+ titleTestNextcloudAbove20Browser);
608+
609+ QCOMPARE (resultClickedBrowser.count (), 1 );
610+ QCOMPARE (resultClickedLocalFile.count (), 0 );
611+
612+ arguments = resultClickedBrowser.takeFirst ();
613+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
614+ QCOMPARE (urlOpenTriggeredViaDesktopServices, resourceUrlTestNextcloudAbove20Browser);
615+
616+ resultClickedBrowser.clear ();
617+ resultClickedLocalFile.clear ();
618+
619+ // Nextcloud 20 opens in local files if the file is available locally
620+ const auto providerIdTestNextcloud20LocalFile = " file" ;
621+ const auto sublineTestNextcloud20LocalFile = " in B/b1" ;
622+ const auto titleTestNextcloud20LocalFile = " b1" ;
623+ const auto resourceUrlTestNextcloud20LocalFile = " http://example.de/files/?dir=/B&scrollto=b1" ;
624+ const auto expectedFileUrlNextcloud20 = localFolderPrefix + " B/b1" ;
625+ model->resultClicked (providerIdTestNextcloud20LocalFile,
626+ QUrl (resourceUrlTestNextcloud20LocalFile), sublineTestNextcloud20LocalFile, titleTestNextcloud20LocalFile);
627+
628+ QCOMPARE (resultClickedBrowser.count (), 0 );
629+ QCOMPARE (resultClickedLocalFile.count (), 1 );
630+
631+ arguments = resultClickedLocalFile.takeFirst ();
632+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
633+ QCOMPARE (urlOpenTriggeredViaDesktopServices, expectedFileUrlNextcloud20);
634+
635+ resultClickedBrowser.clear ();
636+ resultClickedLocalFile.clear ();
637+
638+ // Nextcloud 20 opens in local files if the file is available locally
639+ // The rood directory has a special syntax
640+ const auto providerIdTestNextcloud20LocalFileRoot = " file" ;
641+ const auto sublineTestNextcloud20LocalFileRoot = " in B" ;
642+ const auto titleTestNextcloud20LocalFileRoot = " /B" ;
643+ const auto resourceUrlTestNextcloud20LocalFileRoot = " http://example.de/files/?dir=/&scrollto=B" ;
644+ const auto expectedFileUrlNextcloud20Root = localFolderPrefix + " B" ;
645+ model->resultClicked (providerIdTestNextcloud20LocalFileRoot,
646+ QUrl (resourceUrlTestNextcloud20LocalFileRoot), sublineTestNextcloud20LocalFileRoot, titleTestNextcloud20LocalFileRoot);
647+
648+ QCOMPARE (resultClickedBrowser.count (), 0 );
649+ QCOMPARE (resultClickedLocalFile.count (), 1 );
650+
651+ arguments = resultClickedLocalFile.takeFirst ();
652+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
653+ QCOMPARE (urlOpenTriggeredViaDesktopServices, expectedFileUrlNextcloud20Root);
654+
655+ resultClickedBrowser.clear ();
656+ resultClickedLocalFile.clear ();
657+
658+ // Nextcloud versions above 20 opens in local file if the file is available locally
659+ const auto providerIdTestNextcloudAbove20LocalFile = " file" ;
660+ const auto sublineTestNextcloudAbove20LocalFile = " in A" ;
661+ const auto titleTestNextcloudAbove20LocalFile = " a1" ;
662+ const auto resourceUrlTestNextcloudAbove20LocalFile = " http://example.de/index.php/f/456" ;
663+ const auto expectedFileUrlNextcloudAbove20 = localFolderPrefix + " A/a1" ;
664+ model->resultClicked (providerIdTestNextcloudAbove20LocalFile,
665+ QUrl (resourceUrlTestNextcloudAbove20LocalFile), sublineTestNextcloudAbove20LocalFile,
666+ titleTestNextcloudAbove20LocalFile);
667+
668+ QCOMPARE (resultClickedBrowser.count (), 0 );
669+ QCOMPARE (resultClickedLocalFile.count (), 1 );
670+
671+ arguments = resultClickedLocalFile.takeFirst ();
672+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
673+ QCOMPARE (urlOpenTriggeredViaDesktopServices, expectedFileUrlNextcloudAbove20);
674+
675+ resultClickedBrowser.clear ();
676+ resultClickedLocalFile.clear ();
677+
678+ // Nextcloud versions above 20 opens in local folder if the file is available locally
679+ // In this case the local folder is opened in the root directory
680+ const auto providerIdTestNextcloudAbove20LocalFileRoot = " file" ;
681+ const auto sublineTestNextcloudAbove20LocalFileRoot = " " ;
682+ const auto titleTestNextcloudAbove20LocalFileRoot = " A" ;
683+ const auto resourceUrlTestNextcloudAbove20LocalFileRoot = " http://example.de/index.php/f/789" ;
684+ const auto expectedFileUrlNextcloudAbove20Root = localFolderPrefix + " A" ;
685+ model->resultClicked (providerIdTestNextcloudAbove20LocalFileRoot,
686+ QUrl (resourceUrlTestNextcloudAbove20LocalFileRoot), sublineTestNextcloudAbove20LocalFileRoot,
687+ titleTestNextcloudAbove20LocalFileRoot);
688+
689+ QCOMPARE (resultClickedBrowser.count (), 0 );
690+ QCOMPARE (resultClickedLocalFile.count (), 1 );
691+
692+ arguments = resultClickedLocalFile.takeFirst ();
693+ urlOpenTriggeredViaDesktopServices = arguments.at (0 ).toString ();
694+ QCOMPARE (urlOpenTriggeredViaDesktopServices, expectedFileUrlNextcloudAbove20Root);
695+
696+ resultClickedBrowser.clear ();
697+ resultClickedLocalFile.clear ();
698+
699+ // Accountptr is invalid
700+ model.reset (new OCC::UnifiedSearchResultsListModel (nullptr ));
701+ modelTester.reset (new QAbstractItemModelTester (model.data ()));
702+ const auto providerIdTestNullptr = " file" ;
703+ const auto sublineTestNullptr = " " ;
704+ const auto titleTestNullptr = " A" ;
705+ const auto resourceUrlTestNullptr = " http://example.de/index.php/f/789" ;
706+ model->resultClicked (providerIdTestNullptr,
707+ QUrl (resourceUrlTestNullptr), sublineTestNullptr, titleTestNullptr);
708+
709+ QCOMPARE (resultClickedBrowser.count (), 0 );
710+ QCOMPARE (resultClickedLocalFile.count (), 0 );
711+
712+ resultClickedBrowser.clear ();
713+ resultClickedLocalFile.clear ();
606714 }
607715
608716 void testSetSearchTermResultsError ()
0 commit comments