]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/tests/dolphinmainwindowtest.cpp
Clazy fix
[dolphin.git] / src / tests / dolphinmainwindowtest.cpp
index cd68bb89339d66f662f2620ccf0b98d18f95ec30..b3e52ce2385f545abd79bc73f734049fdf3ab785 100644 (file)
@@ -9,11 +9,15 @@
 #include "dolphintabpage.h"
 #include "dolphintabwidget.h"
 #include "dolphinviewcontainer.h"
+#include "dolphin_generalsettings.h"
 #include "kitemviews/kfileitemmodel.h"
+#include "kitemviews/kfileitemmodelrolesupdater.h"
 #include "kitemviews/kitemlistcontainer.h"
 #include "kitemviews/kitemlistcontroller.h"
 #include "kitemviews/kitemlistselectionmanager.h"
+#include "kitemviews/kitemlistwidget.h"
 #include "testdir.h"
+#include "views/dolphinitemlistview.h"
 
 #include <KActionCollection>
 #include <KConfig>
 #include <QStandardPaths>
 #include <QTest>
 
+#include <kfileitem.h>
+#include <qapplication.h>
+#include <qkeysequence.h>
+#include <qnamespace.h>
 #include <set>
 #include <unordered_set>
 
@@ -46,6 +54,8 @@ private Q_SLOTS:
     void testOpenInNewTabTitle();
     void testNewFileMenuEnabled_data();
     void testNewFileMenuEnabled();
+    void testCreateFileAction();
+    void testCreateFileActionRequiresWritePermission();
     void testWindowTitle_data();
     void testWindowTitle();
     void testFocusLocationBar();
@@ -55,6 +65,8 @@ private Q_SLOTS:
     void testOpenFiles();
     void testAccessibilityTree();
     void testAutoSaveSession();
+    void testInlineRename();
+    void testThumbnailAfterRename();
     void cleanupTestCase();
 
 private:
@@ -64,6 +76,11 @@ private:
 void DolphinMainWindowTest::initTestCase()
 {
     QStandardPaths::setTestModeEnabled(true);
+    // Use fullWidth statusbar during testing, to test out most of the features.
+    GeneralSettings *settings = GeneralSettings::self();
+    settings->setShowStatusBar(GeneralSettings::EnumShowStatusBar::FullWidth);
+    settings->setShowZoomSlider(true);
+    settings->save();
 }
 
 void DolphinMainWindowTest::init()
@@ -137,20 +154,20 @@ void DolphinMainWindowTest::testSyncDesktopAndPhoneUi()
     do {
         QVERIFY2(desktopUiElement.tagName() == phoneUiElement.tagName(),
                  qPrintable(QStringLiteral("Node mismatch: dolphinui.rc/%1::%2 and dolphinuiforphones.rc/%3::%4")
-                                .arg(desktopUiElement.parentNode().toElement().tagName())
-                                .arg(desktopUiElement.tagName())
-                                .arg(phoneUiElement.parentNode().toElement().tagName())
-                                .arg(phoneUiElement.tagName())));
+                                .arg(desktopUiElement.parentNode().toElement().tagName(),
+                                     desktopUiElement.tagName(),
+                                     phoneUiElement.parentNode().toElement().tagName(),
+                                     phoneUiElement.tagName())));
         QCOMPARE(desktopUiElement.text(), phoneUiElement.text());
         const auto desktopUiElementAttributes = desktopUiElement.attributes();
         const auto phoneUiElementAttributes = phoneUiElement.attributes();
         for (int i = 0; i < desktopUiElementAttributes.count(); i++) {
             QVERIFY2(phoneUiElementAttributes.count() >= i,
                      qPrintable(QStringLiteral("Attribute mismatch: dolphinui.rc/%1::%2 has more attributes than dolphinuiforphones.rc/%3::%4")
-                                    .arg(desktopUiElement.parentNode().toElement().tagName())
-                                    .arg(desktopUiElement.tagName())
-                                    .arg(phoneUiElement.parentNode().toElement().tagName())
-                                    .arg(phoneUiElement.tagName())));
+                                    .arg(desktopUiElement.parentNode().toElement().tagName(),
+                                         desktopUiElement.tagName(),
+                                         phoneUiElement.parentNode().toElement().tagName(),
+                                         phoneUiElement.tagName())));
             if (exceptions.count(desktopUiElementAttributes.item(i).nodeName())) {
                 continue;
             }
@@ -160,12 +177,11 @@ void DolphinMainWindowTest::testSyncDesktopAndPhoneUi()
         }
         QVERIFY2(desktopUiElementAttributes.count() == phoneUiElementAttributes.count(),
                  qPrintable(QStringLiteral("Attribute mismatch: dolphinui.rc/%1::%2 has fewer attributes than dolphinuiforphones.rc/%3::%4. %5 < %6")
-                                .arg(desktopUiElement.parentNode().toElement().tagName())
-                                .arg(desktopUiElement.tagName())
-                                .arg(phoneUiElement.parentNode().toElement().tagName())
-                                .arg(phoneUiElement.tagName())
-                                .arg(phoneUiElementAttributes.count())
-                                .arg(desktopUiElementAttributes.count())));
+                                .arg(desktopUiElement.parentNode().toElement().tagName(),
+                                     desktopUiElement.tagName(),
+                                     phoneUiElement.parentNode().toElement().tagName(),
+                                     phoneUiElement.tagName())
+                                .arg(phoneUiElementAttributes.count(), desktopUiElementAttributes.count())));
 
         desktopUiElement = nextUiElement(desktopUiElement);
         phoneUiElement = nextUiElement(phoneUiElement);
@@ -187,7 +203,7 @@ void DolphinMainWindowTest::testClosingTabsWithSearchBoxVisible()
     QVERIFY(tabWidget);
 
     // Show search box on first tab.
-    tabWidget->currentTabPage()->activeViewContainer()->setSearchModeEnabled(true);
+    tabWidget->currentTabPage()->activeViewContainer()->setSearchBarVisible(true);
 
     tabWidget->openNewActivatedTab(QUrl::fromLocalFile(QDir::homePath()));
     QCOMPARE(tabWidget->count(), 2);
@@ -367,6 +383,74 @@ void DolphinMainWindowTest::testNewFileMenuEnabled()
     QTRY_COMPARE(newFileMenu->isEnabled(), expectedEnabled);
 }
 
+void DolphinMainWindowTest::testCreateFileAction()
+{
+    QScopedPointer<TestDir> testDir{new TestDir()};
+    QString testDirUrl(QDir::cleanPath(testDir->url().toString()));
+    m_mainWindow->openDirectories({testDirUrl}, false);
+    m_mainWindow->show();
+    QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+    QVERIFY(m_mainWindow->isVisible());
+
+    QCOMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+    auto createFileAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_file"));
+    QTRY_COMPARE(createFileAction->isEnabled(), true);
+
+    createFileAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_N));
+
+    QSignalSpy createFileActionSpy(createFileAction, &QAction::triggered);
+
+    QTest::keyClick(QApplication::activeWindow(), Qt::Key_N, Qt::ControlModifier | Qt::AltModifier);
+
+    QTRY_COMPARE(createFileActionSpy.count(), 1);
+
+    QTRY_VERIFY(QApplication::activeModalWidget() != nullptr);
+
+    auto newFileDialog = QApplication::activeModalWidget()->focusWidget();
+    QTest::keyClick(newFileDialog, Qt::Key_X);
+    QTest::keyClick(newFileDialog, Qt::Key_Y);
+    QTest::keyClick(newFileDialog, Qt::Key_Z);
+    QTest::keyClick(newFileDialog, Qt::Key_Enter);
+
+    QTRY_COMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 1);
+
+    QFile file(testDir->url().toLocalFile() + "/xyz.txt");
+    QVERIFY(file.exists());
+    QCOMPARE(file.size(), 0);
+}
+
+ void DolphinMainWindowTest::testCreateFileActionRequiresWritePermission()
+{
+    QScopedPointer<TestDir> testDir{new TestDir()};
+    QString testDirUrl(QDir::cleanPath(testDir->url().toString()));
+    auto testDirAsFile = QFile(testDir->url().toLocalFile());
+
+    // make test dir read only
+    QVERIFY(testDirAsFile.setPermissions(QFileDevice::ReadOwner));
+
+    m_mainWindow->openDirectories({testDirUrl}, false);
+    m_mainWindow->show();
+    QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+    QVERIFY(m_mainWindow->isVisible());
+
+    QCOMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+    auto createFileAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_file"));
+    QTRY_COMPARE(createFileAction->isEnabled(), false);
+
+    createFileAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_N));
+    QTest::keyClick(QApplication::activeWindow(), Qt::Key_N, Qt::ControlModifier | Qt::AltModifier);
+
+    QTRY_COMPARE(QApplication::activeModalWidget(), nullptr);
+
+    QTRY_COMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+    QTRY_COMPARE(createFileAction->isEnabled(), false);
+
+    QVERIFY(m_mainWindow->isVisible());
+}
+
 void DolphinMainWindowTest::testWindowTitle_data()
 {
     QTest::addColumn<QUrl>("activeViewUrl");
@@ -456,6 +540,18 @@ void DolphinMainWindowTest::testFocusPlacesPanel()
     showPlacesPanelAction->trigger();
     QVERIFY(placesPanel->isVisible());
     QVERIFY2(placesPanel->hasFocus(), "Enabling the Places panel should move keyboard focus there.");
+
+    /// Test that activating a place always moves focus to the view.
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key::Key_Enter);
+    QVERIFY2(m_mainWindow->activeViewContainer()->isAncestorOf(QApplication::focusWidget()),
+             "Activating a place should move focus to the view that loads that place.");
+
+    focusPlacesPanelAction->trigger();
+    QVERIFY(placesPanel->hasFocus());
+
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key::Key_Enter);
+    QVERIFY2(m_mainWindow->activeViewContainer()->isAncestorOf(QApplication::focusWidget()),
+             "Activating a place should move focus to the view even if the view already has that place loaded.");
 }
 
 /**
@@ -829,7 +925,7 @@ void DolphinMainWindowTest::testAccessibilityTree()
                                                                                       // after going forwards which is probably not intended.
         }
     }
-    QCOMPARE_GE(testedObjectsSizeAfterTraversingForwards, 12); // The test did not reach many objects while using the Tab key to move through Dolphin. Did the
+    QCOMPARE_GE(testedObjectsSizeAfterTraversingForwards, 11); // The test did not reach many objects while using the Tab key to move through Dolphin. Did the
                                                                // test run correctly?
 }
 
@@ -869,6 +965,105 @@ void DolphinMainWindowTest::testAutoSaveSession()
     m_mainWindow->setSessionAutoSaveEnabled(false);
 }
 
+void DolphinMainWindowTest::testInlineRename()
+{
+    QScopedPointer<TestDir> testDir{new TestDir()};
+    testDir->createFiles({"aaaa", "bbbb", "cccc", "dddd"});
+    m_mainWindow->openDirectories({testDir->url()}, false);
+    m_mainWindow->show();
+    QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+    QVERIFY(m_mainWindow->isVisible());
+
+    DolphinView *view = m_mainWindow->activeViewContainer()->view();
+    QSignalSpy viewDirectoryLoadingCompletedSpy(view, &DolphinView::directoryLoadingCompleted);
+    QSignalSpy itemsReorderedSpy(view->m_model, &KFileItemModel::itemsMoved);
+    QSignalSpy modelDirectoryLoadingCompletedSpy(view->m_model, &KFileItemModel::directoryLoadingCompleted);
+
+    QVERIFY(viewDirectoryLoadingCompletedSpy.wait());
+    QTest::qWait(500); // we need to wait for the file widgets to become visible
+    view->markUrlsAsSelected({QUrl(testDir->url().toString() + "/aaaa")});
+    view->updateViewState();
+    view->renameSelectedItems();
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Left);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_E);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Down);
+
+    QVERIFY(itemsReorderedSpy.wait());
+    QVERIFY(view->m_view->m_editingRole);
+    KItemListWidget *widget = view->m_view->m_visibleItems.value(view->m_view->firstVisibleIndex());
+    QVERIFY(!widget->editedRole().isEmpty());
+
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Left);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_A);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Down);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Down);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Left);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_A);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Down);
+
+    QVERIFY(itemsReorderedSpy.wait());
+    QVERIFY(view->m_view->m_editingRole);
+    widget = view->m_view->m_visibleItems.value(view->m_view->lastVisibleIndex());
+    QVERIFY(!widget->editedRole().isEmpty());
+
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Escape);
+    QVERIFY(widget->isCurrent());
+    view->m_model->refreshDirectory(testDir->url());
+    QVERIFY(modelDirectoryLoadingCompletedSpy.wait());
+
+    QCOMPARE(view->m_model->fileItem(0).name(), "abbbb");
+    QCOMPARE(view->m_model->fileItem(1).name(), "adddd");
+    QCOMPARE(view->m_model->fileItem(2).name(), "cccc");
+    QCOMPARE(view->m_model->fileItem(3).name(), "eaaaa");
+    QCOMPARE(view->m_model->count(), 4);
+}
+
+void DolphinMainWindowTest::testThumbnailAfterRename()
+{
+    // Create testdir and red square jpg for testing
+    QScopedPointer<TestDir> testDir{new TestDir()};
+    QImage testImage(256, 256, QImage::Format_Mono);
+    testImage.setColorCount(1);
+    testImage.setColor(0, qRgba(255, 0, 0, 255)); // Index #0 = Red
+    for (short x = 0; x < 256; ++x) {
+        for (short y = 0; y < 256; ++y) {
+            testImage.setPixel(x, y, 0);
+        }
+    }
+    testImage.save(testDir.data()->path() + "/a.jpg");
+
+    // Open dir and show it
+    m_mainWindow->openDirectories({testDir->url()}, false);
+    DolphinView *view = m_mainWindow->activeViewContainer()->view();
+    // Prepare signal spies
+    QSignalSpy viewDirectoryLoadingCompletedSpy(view, &DolphinView::directoryLoadingCompleted);
+    QSignalSpy itemsChangedSpy(view->m_model, &KFileItemModel::itemsChanged);
+    QSignalSpy modelDirectoryLoadingCompletedSpy(view->m_model, &KFileItemModel::directoryLoadingCompleted);
+    QSignalSpy previewUpdatedSpy(view->m_view->m_modelRolesUpdater, &KFileItemModelRolesUpdater::previewJobFinished);
+    // Show window and check that our preview has been updated, then wait for it to appear
+    m_mainWindow->show();
+    QVERIFY(viewDirectoryLoadingCompletedSpy.wait());
+    QVERIFY(previewUpdatedSpy.wait());
+    QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+    QVERIFY(m_mainWindow->isVisible());
+    QTest::qWait(500); // we need to wait for the file widgets to become visible
+
+    // Set image selected and rename it to b.jpg, make sure editing role is working
+    view->markUrlsAsSelected({QUrl(testDir->url().toString() + "/a.jpg")});
+    view->updateViewState();
+    view->renameSelectedItems();
+    QVERIFY(view->m_view->m_editingRole);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_B);
+    QTest::keyClick(QApplication::focusWidget(), Qt::Key_Enter);
+    QVERIFY(itemsChangedSpy.wait()); // Make sure that rename worked
+
+    // Check that preview gets updated and filename is correct
+    QVERIFY(previewUpdatedSpy.wait());
+    QVERIFY(!view->m_view->m_editingRole);
+    QCOMPARE(view->m_model->fileItem(0).name(), "b.jpg");
+    QCOMPARE(view->m_model->count(), 1);
+}
+
 void DolphinMainWindowTest::cleanupTestCase()
 {
     m_mainWindow->showNormal();