File indexing completed on 2025-03-02 05:12:12

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003     SPDX-FileCopyrightText: 2021 Benjamin Port <benjamin.port@enioka.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "../kcm.h"
0009 #include "../lookandfeelmanager.h"
0010 // Qt
0011 #include <KJob>
0012 #include <KPackage/Package>
0013 #include <KPackage/PackageJob>
0014 #include <KSycoca>
0015 #include <QSignalSpy>
0016 #include <QTest>
0017 
0018 using namespace Qt::StringLiterals;
0019 
0020 class KcmTest : public QObject
0021 {
0022     /**
0023      *  Following tests ensure lookandfeel configuration are saved to kdedefaults,
0024      *  and configuration (kdeglobals, kwinrc...) from XDG_CONFIG_HOME return default value.
0025      *
0026      *  Because test don't have a modified XDG_CONFIG_DIRS with kdedefault dir added,
0027      *  we can easily check XDG_CONFIG_HOME values have default value and still using cascade/global behavior
0028      */
0029     Q_OBJECT
0030 private Q_SLOTS:
0031     void initTestCase();
0032     void cleanupTestCase();
0033     void testWidgetStyle();
0034     void testColors();
0035     void testIcons();
0036     void testPlasmaTheme();
0037     void testCursorTheme();
0038     void testSplashScreen();
0039     void testLockScreen();
0040     void testWindowSwitcher();
0041     void testKCMSave();
0042 
0043 private:
0044     QDir m_configDir;
0045     QDir m_dataDir;
0046     KCMLookandFeel *m_KCMLookandFeel;
0047 };
0048 
0049 void KcmTest::initTestCase()
0050 {
0051     QStandardPaths::setTestModeEnabled(true);
0052     qunsetenv("XDG_CONFIG_DIRS");
0053 
0054     m_configDir = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
0055     m_configDir.removeRecursively();
0056 
0057     m_dataDir = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
0058     m_dataDir.removeRecursively();
0059 
0060     QVERIFY(m_configDir.mkpath("."));
0061 
0062     // we need an existing colorscheme file, even if empty
0063     QVERIFY(m_dataDir.mkpath(QStringLiteral("color-schemes")));
0064     QFile f(m_dataDir.path() + QStringLiteral("/color-schemes/TestValue.colors"));
0065     f.open(QIODevice::WriteOnly);
0066     f.close();
0067 
0068     const QString packagePath = QFINDTESTDATA("lookandfeel");
0069     const QString packageRoot = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/plasma/look-and-feel/";
0070     auto installJob = KPackage::PackageJob::install(QStringLiteral("Plasma/LookAndFeel"), packagePath, packageRoot);
0071     connect(installJob, &KJob::result, this, [installJob]() {
0072         QCOMPARE(installJob->errorText(), QString());
0073         QCOMPARE(installJob->error(), KJob::NoError);
0074         QVERIFY(installJob->package().isValid());
0075     });
0076     QSignalSpy spy(installJob, &KPackage::PackageJob::finished);
0077     spy.wait();
0078 
0079     KConfig config(u"kdeglobals"_s);
0080     KConfigGroup cg(&config, u"KDE"_s);
0081     cg.writeEntry("LookAndFeelPackage", "org.kde.test");
0082     cg.sync();
0083     m_KCMLookandFeel = new KCMLookandFeel(nullptr, KPluginMetaData());
0084     m_KCMLookandFeel->load();
0085 }
0086 
0087 void KcmTest::cleanupTestCase()
0088 {
0089     m_configDir.removeRecursively();
0090     m_dataDir.removeRecursively();
0091 }
0092 
0093 void KcmTest::testWidgetStyle()
0094 {
0095     // We have to use an actual theme name here because setWidgetStyle checks
0096     // if the theme can actually be used before it changes the config
0097     m_KCMLookandFeel->lookAndFeel()->setWidgetStyle(QStringLiteral("Fusion"));
0098 
0099     KConfig config(QStringLiteral("kdeglobals"));
0100     KConfigGroup cg(&config, u"KDE"_s);
0101     QCOMPARE(cg.readEntry("widgetStyle", QString()), QString());
0102 
0103     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kdeglobals", KConfig::SimpleConfig);
0104     KConfigGroup cgd(&configDefault, u"KDE"_s);
0105     QCOMPARE(cgd.readEntry("widgetStyle", QString()), QStringLiteral("Fusion"));
0106 
0107     // Test that a fake style is not actually written to config
0108     m_KCMLookandFeel->lookAndFeel()->setWidgetStyle(QStringLiteral("customStyle"));
0109     QCOMPARE(cgd.readEntry("widgetStyle", QString()), QStringLiteral("Fusion"));
0110 }
0111 
0112 void KcmTest::testColors()
0113 {
0114     // TODO: test colorFile as well
0115     m_KCMLookandFeel->lookAndFeel()->setColors(QStringLiteral("customTestValue"), QString());
0116 
0117     KConfig config(QStringLiteral("kdeglobals"));
0118     KConfigGroup cg(&config, u"General"_s);
0119     QCOMPARE(cg.readEntry("ColorScheme", QString()), QString());
0120 
0121     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kdeglobals", KConfig::SimpleConfig);
0122     KConfigGroup cgd(&configDefault, u"General"_s);
0123     QCOMPARE(cgd.readEntry("ColorScheme", QString()), QStringLiteral("customTestValue"));
0124 }
0125 
0126 void KcmTest::testIcons()
0127 {
0128     m_KCMLookandFeel->lookAndFeel()->setIcons(QStringLiteral("customTestValue"));
0129 
0130     KConfig config(QStringLiteral("kdeglobals"));
0131     KConfigGroup cg(&config, u"Icons"_s);
0132     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0133 
0134     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kdeglobals", KConfig::SimpleConfig);
0135     KConfigGroup cgd(&configDefault, u"Icons"_s);
0136     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0137 }
0138 
0139 void KcmTest::testPlasmaTheme()
0140 {
0141     m_KCMLookandFeel->lookAndFeel()->setPlasmaTheme(QStringLiteral("customTestValue"));
0142 
0143     KConfig config(QStringLiteral("plasmarc"));
0144     KConfigGroup cg(&config, u"Theme"_s);
0145     QCOMPARE(cg.readEntry("name", QString()), QString());
0146 
0147     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/plasmarc", KConfig::SimpleConfig);
0148     KConfigGroup cgd(&configDefault, u"Theme"_s);
0149     QCOMPARE(cgd.readEntry("name", QString()), QStringLiteral("customTestValue"));
0150 }
0151 
0152 void KcmTest::testCursorTheme()
0153 {
0154     m_KCMLookandFeel->lookAndFeel()->setCursorTheme(QStringLiteral("customTestValue"));
0155 
0156     KConfig config(QStringLiteral("kcminputrc"));
0157     KConfigGroup cg(&config, u"Mouse"_s);
0158     QCOMPARE(cg.readEntry("cursorTheme", QString()), QString());
0159 
0160     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kcminputrc", KConfig::SimpleConfig);
0161     KConfigGroup cgd(&configDefault, u"Mouse"_s);
0162     QCOMPARE(cgd.readEntry("cursorTheme", QString()), QStringLiteral("customTestValue"));
0163 }
0164 
0165 void KcmTest::testSplashScreen()
0166 {
0167     m_KCMLookandFeel->lookAndFeel()->setSplashScreen(QStringLiteral("customTestValue"));
0168 
0169     KConfig config(QStringLiteral("ksplashrc"));
0170     KConfigGroup cg(&config, u"KSplash"_s);
0171     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0172     QCOMPARE(cg.readEntry("Engine", QString()), QString());
0173 
0174     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/ksplashrc", KConfig::SimpleConfig);
0175     KConfigGroup cgd(&configDefault, u"KSplash"_s);
0176     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0177     QCOMPARE(cgd.readEntry("Engine", QString()), QStringLiteral("KSplashQML"));
0178 }
0179 
0180 void KcmTest::testLockScreen()
0181 {
0182     m_KCMLookandFeel->lookAndFeel()->setLockScreen(QStringLiteral("customTestValue"));
0183 
0184     KConfig config(QStringLiteral("kscreenlockerrc"));
0185     KConfigGroup cg(&config, u"Greeter"_s);
0186     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0187 
0188     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kscreenlockerrc", KConfig::SimpleConfig);
0189     KConfigGroup cgd(&configDefault, u"Greeter"_s);
0190     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0191 }
0192 
0193 void KcmTest::testWindowSwitcher()
0194 {
0195     m_KCMLookandFeel->lookAndFeel()->setWindowSwitcher(QStringLiteral("customTestValue"));
0196 
0197     KConfig config(QStringLiteral("kwinrc"));
0198     KConfigGroup cg(&config, u"TabBox"_s);
0199     QCOMPARE(cg.readEntry("LayoutName", QString()), QString());
0200 
0201     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kwinrc", KConfig::SimpleConfig);
0202     KConfigGroup cgd(&configDefault, u"TabBox"_s);
0203     QCOMPARE(cgd.readEntry("LayoutName", QString()), QStringLiteral("customTestValue"));
0204 }
0205 
0206 void KcmTest::testKCMSave()
0207 {
0208     // TODO: Previous bussiness code was effectively filtering every item from
0209     // getting save, so the values would remain those set in the previous tests.
0210     // This is the simpler fix to emulate the old behavior.
0211     // Ideally we would test for the real items in the default theme or better,
0212     // in a custom-made test package.
0213     m_KCMLookandFeel->setSelectedContents(LookAndFeelManager::Empty);
0214 
0215     m_KCMLookandFeel->save();
0216 
0217     // On real setup we read entries from kdedefaults directory (XDG_CONFIG_DIRS is modified but not in test scenario)
0218 
0219     KConfig config(QStringLiteral("kdeglobals"));
0220     KConfig configDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kdeglobals", KConfig::SimpleConfig);
0221     KConfigGroup cg(&config, u"KDE"_s);
0222     KConfigGroup cgd(&configDefault, u"KDE"_s);
0223     // See comment in testWidgetStyle
0224     QCOMPARE(cg.readEntry("widgetStyle", QString()), QString());
0225     QCOMPARE(cgd.readEntry("widgetStyle", QString()), QStringLiteral("Fusion"));
0226 
0227     cg = KConfigGroup(&config, u"General"_s);
0228     cgd = KConfigGroup(&configDefault, u"General"_s);
0229     // save() capitalizes the ColorScheme
0230     QCOMPARE(cg.readEntry("ColorScheme", QString()), QString());
0231     QCOMPARE(cgd.readEntry("ColorScheme", QString()), QStringLiteral("customTestValue"));
0232 
0233     cg = KConfigGroup(&config, u"Icons"_s);
0234     cgd = KConfigGroup(&configDefault, u"Icons"_s);
0235     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0236     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0237 
0238     KConfig plasmaConfig(QStringLiteral("plasmarc"));
0239     KConfig plasmaConfigDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/plasmarc", KConfig::SimpleConfig);
0240     cg = KConfigGroup(&plasmaConfig, u"Theme"_s);
0241     cgd = KConfigGroup(&plasmaConfigDefault, u"Theme"_s);
0242     QCOMPARE(cg.readEntry("name", QString()), QString());
0243     QCOMPARE(cgd.readEntry("name", QString()), QStringLiteral("customTestValue"));
0244 
0245     KConfig inputConfig(QStringLiteral("kcminputrc"));
0246     KConfig inputConfigDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kcminputrc", KConfig::SimpleConfig);
0247     cg = KConfigGroup(&inputConfig, u"Mouse"_s);
0248     cgd = KConfigGroup(&inputConfigDefault, u"Mouse"_s);
0249     QCOMPARE(cg.readEntry("cursorTheme", QString()), QString());
0250     QCOMPARE(cgd.readEntry("cursorTheme", QString()), QStringLiteral("customTestValue"));
0251 
0252     KConfig splashConfig(QStringLiteral("ksplashrc"));
0253     KConfig splashConfigDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/ksplashrc", KConfig::SimpleConfig);
0254     cg = KConfigGroup(&splashConfig, u"KSplash"_s);
0255     cgd = KConfigGroup(&splashConfigDefault, u"KSplash"_s);
0256     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0257     QCOMPARE(cg.readEntry("Engine", QString()), QString());
0258     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0259     QCOMPARE(cgd.readEntry("Engine", QString()), QStringLiteral("KSplashQML"));
0260 
0261     KConfig lockerConfig(QStringLiteral("kscreenlockerrc"));
0262     KConfig lockerConfigDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kscreenlockerrc",
0263                                 KConfig::SimpleConfig);
0264     cg = KConfigGroup(&lockerConfig, u"Greeter"_s);
0265     cgd = KConfigGroup(&lockerConfigDefault, u"Greeter"_s);
0266     QCOMPARE(cg.readEntry("Theme", QString()), QString());
0267     QCOMPARE(cgd.readEntry("Theme", QString()), QStringLiteral("customTestValue"));
0268 
0269     KConfig kwinConfig(QStringLiteral("kwinrc"));
0270     KConfig kwinConfigDefault(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/kwinrc", KConfig::SimpleConfig);
0271     cg = KConfigGroup(&kwinConfig, u"TabBox"_s);
0272     cgd = KConfigGroup(&kwinConfigDefault, u"TabBox"_s);
0273     QCOMPARE(cg.readEntry("LayoutName", QString()), QString());
0274     QCOMPARE(cgd.readEntry("LayoutName", QString()), QStringLiteral("customTestValue"));
0275 }
0276 
0277 QTEST_MAIN(KcmTest)
0278 #include "kcmtest.moc"