File indexing completed on 2024-05-12 05:37:54

0001 /*
0002     SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "../klipper.h"
0008 #include "../history.h"
0009 #include "../historyitem.h"
0010 #include "../historymodel.h"
0011 
0012 #include <KConfigGroup>
0013 #include <KSharedConfig>
0014 
0015 #include <QScopeGuard>
0016 #include <QTest>
0017 
0018 class KlipperTest : public QObject
0019 {
0020     Q_OBJECT
0021 
0022 private Q_SLOTS:
0023     void initTestCase();
0024 
0025     /**
0026         The mime data from Wayland clipboard is not the exact same image, so two
0027         image items are listed (first time restarting plasmashell). But after
0028         images are saved to local, they have the same uuid again. So klipper
0029         starts to become confused after the second time restarting plasmashell.
0030 
0031         This is caused by QPixmap::from(QImage).toImage() erasing metadata in the
0032         image, and Wayland clipboard is async, so another identical image is added
0033         to clipboard.
0034 
0035         This test tries to reproduce the process to trigger the original bug by
0036 
0037         1. Enable image history
0038         2. Copy faulty image data
0039         3. Reload Klipper
0040 
0041         @see https://bugs.kde.org/465225
0042      */
0043     void testBug465225();
0044 };
0045 
0046 void KlipperTest::initTestCase()
0047 {
0048     QStandardPaths::setTestModeEnabled(true);
0049 }
0050 
0051 void KlipperTest::testBug465225()
0052 {
0053     const QString folderPath =
0054         QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QDir::separator() + QStringLiteral("klipper") + QDir::separator();
0055     QVERIFY(QDir().mkpath(folderPath));
0056     QVERIFY(QFile(QFINDTESTDATA("./data/bug465225.lst")).copy(QDir(folderPath).absoluteFilePath(QStringLiteral("history2.lst"))));
0057 
0058     const QString fileName = QStringLiteral("klipperrc");
0059     QScopeGuard cleanup([&folderPath, &fileName] {
0060         QDir(folderPath).removeRecursively();
0061         QFile(QStandardPaths::locate(QStandardPaths::GenericConfigLocation, fileName)).remove();
0062     });
0063 
0064     // Prepare config
0065     auto klipperConfig = KSharedConfig::openConfig(fileName, KConfig::NoGlobals);
0066     KConfigGroup config(klipperConfig, QStringLiteral("General"));
0067     config.writeEntry("IgnoreImages", false);
0068     config.writeEntry("MaxClipItems", 30);
0069     QVERIFY(config.sync());
0070 
0071     // Load the history file which contains faulty image data
0072     {
0073         auto klipper = std::make_unique<Klipper>(this, klipperConfig);
0074         QCOMPARE(klipper->history()->model()->rowCount(), 1);
0075         QCOMPARE(klipper->history()->first()->type(), HistoryItemType::Image);
0076 
0077         auto mimeData = klipper->history()->first()->mimeData();
0078 
0079         QClipboard *clipboard = qGuiApp->clipboard();
0080         clipboard->setText(QDateTime::currentDateTime().toString());
0081         QCoreApplication::processEvents();
0082         QCOMPARE(klipper->history()->model()->rowCount(), 2);
0083 
0084         clipboard->setMimeData(mimeData);
0085         QCoreApplication::processEvents();
0086         QCOMPARE(klipper->history()->model()->rowCount(), 2);
0087         QCOMPARE(klipper->history()->first()->type(), HistoryItemType::Image);
0088 
0089         klipper->saveClipboardHistory();
0090     }
0091 
0092     // Now load the history file again
0093     {
0094         auto klipper = std::make_unique<Klipper>(this, klipperConfig);
0095         QCOMPARE(klipper->history()->model()->rowCount(), 2);
0096         QCOMPARE(klipper->history()->first()->type(), HistoryItemType::Image);
0097         QVERIFY(klipper->history()->first()->uuid() != klipper->history()->first()->next_uuid());
0098     }
0099 }
0100 
0101 QTEST_MAIN(KlipperTest)
0102 #include "klippertest.moc"