MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.4% 84 / 0 / 89
Functions: 100.0% 12 / 0 / 12
Branches: 76.2% 109 / 0 / 143

service/DesktopIntegration.cpp
Line Branch Exec Source
1 #include "DesktopIntegration.h"
2
3 #include <QByteArray>
4 #include <QDBusConnection>
5 #include <QDBusConnectionInterface>
6 #include <QDBusReply>
7 #include <QGuiApplication>
8 #include <QLoggingCategory>
9 #include <QString>
10
11
4/7
✓ Branch 2 → 3 taken 23 times.
✓ Branch 2 → 8 taken 1591 times.
✓ Branch 4 → 5 taken 23 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 23 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
1614 Q_LOGGING_CATEGORY(lcDesktopIntegration, "mailjd.desktop.integration")
12
13 namespace {
14 #ifdef MAILJD_UNIT_TEST
15 std::optional<DesktopCapabilities> capabilityOverride;
16 #endif
17
18 4 QString validPlatformValue(const QVariantMap &data, const QString &key) {
19
2/2
✓ Branch 3 → 4 taken 4 times.
✓ Branch 4 → 5 taken 4 times.
4 const QString value = data.value(key).toString();
20
5/6
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 11 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 3 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 3 times.
4 if (value.isEmpty() || value.size() > 4096)
21 1 return {};
22
2/2
✓ Branch 27 → 17 taken 28 times.
✓ Branch 27 → 28 taken 2 times.
30 for (const QChar character : value) {
23
5/6
✓ Branch 18 → 19 taken 28 times.
✗ Branch 18 → 21 not taken.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 22 taken 27 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 26 taken 27 times.
28 if (character.isNull() || character.category() == QChar::Other_Control)
24 1 return {};
25 }
26 2 return value;
27 4 }
28
29 3228 bool serviceAvailable(const QString &name) {
30
2/2
✓ Branch 2 → 3 taken 3228 times.
✓ Branch 3 → 4 taken 3228 times.
3228 auto *interface = QDBusConnection::sessionBus().interface();
31
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 3228 times.
3228 if (!interface)
32 ✗ return false;
33
1/1
✓ Branch 7 → 8 taken 3228 times.
3228 const QDBusReply<bool> reply = interface->isServiceRegistered(name);
34
4/5
✓ Branch 8 → 9 taken 3228 times.
✓ Branch 9 → 10 taken 3228 times.
✗ Branch 9 → 13 not taken.
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 13 taken 3226 times.
3228 return reply.isValid() && reply.value();
35 3228 }
36
37 1614 bool isKdeSession() {
38
2/2
✓ Branch 2 → 3 taken 1614 times.
✓ Branch 3 → 4 taken 1614 times.
1614 const QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toUpper();
39
2/2
✓ Branch 5 → 6 taken 1614 times.
✓ Branch 6 → 7 taken 1614 times.
1614 const QByteArray sessionDesktop = qgetenv("XDG_SESSION_DESKTOP").toUpper();
40
1/2
✓ Branch 12 → 13 taken 1614 times.
✗ Branch 12 → 20 not taken.
1614 return qEnvironmentVariableIsSet("KDE_FULL_SESSION") ||
41
2/5
✓ Branch 10 → 11 taken 1614 times.
✓ Branch 15 → 16 taken 1614 times.
✗ Branch 15 → 20 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
4842 currentDesktop.split(':').contains("KDE") ||
42
3/7
✓ Branch 13 → 14 taken 1614 times.
✓ Branch 17 → 18 taken 1614 times.
✗ Branch 17 → 20 not taken.
✓ Branch 25 → 26 taken 1614 times.
✗ Branch 25 → 27 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
4842 currentDesktop.split(':').contains("PLASMA") ||
43
3/6
✓ Branch 9 → 10 taken 1614 times.
✗ Branch 9 → 20 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 1614 times.
✓ Branch 23 → 24 taken 1614 times.
✗ Branch 23 → 25 not taken.
6456 sessionDesktop == "KDE" || sessionDesktop == "PLASMA";
44 1614 }
45 } // namespace
46
47 1615 DesktopCapabilities DesktopIntegration::capabilities() {
48 #ifdef MAILJD_UNIT_TEST
49
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 6 taken 7 times.
8 if (capabilityOverride)
50 1 return *capabilityOverride;
51 #endif
52 1614 DesktopCapabilities result;
53
2/2
✓ Branch 2 → 3 taken 1607 times.
✓ Branch 6 → 7 taken 7 times.
1614 result.kdeSession = isKdeSession();
54
4/4
✓ Branch 3 → 4 taken 1607 times.
✓ Branch 4 → 5 taken 1607 times.
✓ Branch 7 → 8 taken 7 times.
✓ Branch 8 → 9 taken 7 times.
1614 result.sessionBus = QDBusConnection::sessionBus().isConnected();
55
2/4
✓ Branch 6 → 7 taken 1607 times.
✗ Branch 6 → 20 not taken.
✓ Branch 10 → 11 taken 7 times.
✗ Branch 10 → 24 not taken.
1614 if (result.sessionBus) {
56 1614 result.notifications =
57
2/2
✓ Branch 10 → 11 taken 1607 times.
✓ Branch 14 → 15 taken 7 times.
1614 serviceAvailable(QStringLiteral("org.freedesktop.Notifications"));
58 1614 result.statusNotifierHost =
59
2/2
✓ Branch 16 → 17 taken 1607 times.
✓ Branch 20 → 21 taken 7 times.
1614 serviceAvailable(QStringLiteral("org.kde.StatusNotifierWatcher"));
60 }
61 1614 return result;
62 }
63
64 1619 DesktopBackends DesktopIntegration::select(
65 const DesktopCapabilities &capabilities, bool kdeCompiled,
66 bool windowSystemCompiled) {
67 1619 DesktopBackends result;
68
4/4
✓ Branch 2 → 3 taken 1614 times.
✓ Branch 2 → 6 taken 5 times.
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 6 taken 1611 times.
1622 result.kdeNotifications = kdeCompiled && capabilities.kdeSession &&
69
2/2
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 6 taken 1 time.
3 capabilities.notifications;
70
4/4
✓ Branch 7 → 8 taken 1614 times.
✓ Branch 7 → 11 taken 5 times.
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 11 taken 1611 times.
1622 result.kdeStatusNotifier = kdeCompiled && capabilities.kdeSession &&
71
2/2
✓ Branch 9 → 10 taken 2 times.
✓ Branch 9 → 11 taken 1 time.
3 capabilities.statusNotifierHost;
72 1619 result.kdeDbusService =
73
5/6
✓ Branch 12 → 13 taken 1614 times.
✓ Branch 12 → 16 taken 5 times.
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 16 taken 1611 times.
✓ Branch 14 → 15 taken 3 times.
✗ Branch 14 → 16 not taken.
1619 kdeCompiled && capabilities.kdeSession && capabilities.sessionBus;
74 // KWindowSystem's activation-token bridge is a window-system facility, not
75 // a Plasma-only backend. It is required for token-aware activation on
76 // Mutter and other Wayland compositors too.
77 1619 result.kdeWindowActivation = windowSystemCompiled;
78 1619 return result;
79 }
80
81 1614 DesktopBackends DesktopIntegration::current() {
82 #ifdef MAILJD_KDE_INTEGRATION
83 1610 constexpr bool kdeCompiled = true;
84 #else
85 4 constexpr bool kdeCompiled = false;
86 #endif
87 #ifdef MAILJD_HAVE_KWINDOWSYSTEM
88 1607 constexpr bool windowSystemCompiled = true;
89 #else
90 7 constexpr bool windowSystemCompiled = false;
91 #endif
92 const DesktopBackends result =
93
1/1
✓ Branch 2 → 3 taken 1614 times.
1614 select(capabilities(), kdeCompiled, windowSystemCompiled);
94
4/4
✓ Branch 4 → 5 taken 1614 times.
✓ Branch 8 → 9 taken 1614 times.
✓ Branch 32 → 6 taken 1614 times.
✓ Branch 32 → 33 taken 1614 times.
3228 qCInfo(lcDesktopIntegration)
95
1/1
✓ Branch 9 → 10 taken 1614 times.
1614 << "selected desktop backends: notifications="
96
2/3
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 1614 times.
✓ Branch 13 → 14 taken 1614 times.
1614 << (result.kdeNotifications ? "KDE" : "freedesktop")
97
3/4
✓ Branch 14 → 15 taken 1614 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1614 times.
✓ Branch 18 → 19 taken 1614 times.
1614 << "tray=" << (result.kdeStatusNotifier ? "KDE" : "Qt")
98
3/4
✓ Branch 19 → 20 taken 1614 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 1614 times.
✓ Branch 23 → 24 taken 1614 times.
1614 << "single-instance=" << (result.kdeDbusService ? "KDE" : "D-Bus")
99
4/4
✓ Branch 24 → 25 taken 1614 times.
✓ Branch 25 → 26 taken 1607 times.
✓ Branch 25 → 27 taken 7 times.
✓ Branch 28 → 29 taken 1614 times.
1614 << "activation=" << (result.kdeWindowActivation ? "KDE" : "Qt");
100 1614 return result;
101 }
102
103 6 StatusNotifierState DesktopIntegration::statusNotifierState(
104 int unreadCount, bool windowVisible) {
105 // NeedsAttention is deliberately not part of this policy. Plasma may blink
106 // or pulse items in that state, while an unread counter is persistent
107 // application status rather than a request for immediate intervention.
108
4/4
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 4 taken 2 times.
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 2 times.
6 return (unreadCount > 0 || !windowVisible) ? StatusNotifierState::Active
109 6 : StatusNotifierState::Passive;
110 }
111
112 DesktopActivationContext
113 2 DesktopIntegration::activationContext(const QVariantMap &platformData) {
114 2 DesktopActivationContext result;
115 result.activationToken =
116
1/1
✓ Branch 5 → 6 taken 2 times.
2 validPlatformValue(platformData, QStringLiteral("activation-token"));
117
1/1
✓ Branch 13 → 14 taken 2 times.
4 result.desktopStartupId = validPlatformValue(
118 6 platformData, QStringLiteral("desktop-startup-id"));
119 2 return result;
120 ✗ }
121
122 2 QVariantMap DesktopIntegration::currentActivationPlatformData() {
123 2 QVariantMap result;
124 const QString activationToken =
125
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 3 → 4 taken 2 times.
2 QString::fromUtf8(qgetenv("XDG_ACTIVATION_TOKEN"));
126
2/2
✓ Branch 5 → 6 taken 2 times.
✓ Branch 6 → 7 taken 2 times.
2 const QString startupId = QString::fromUtf8(qgetenv("DESKTOP_STARTUP_ID"));
127
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 19 taken 2 times.
2 if (!activationToken.isEmpty())
128 ✗ result.insert(QStringLiteral("activation-token"), activationToken);
129
1/2
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 30 taken 2 times.
2 if (!startupId.isEmpty())
130 ✗ result.insert(QStringLiteral("desktop-startup-id"), startupId);
131 2 return result;
132 2 }
133
134 17 bool DesktopIntegration::isWaylandSession() {
135
2/2
✓ Branch 2 → 3 taken 17 times.
✓ Branch 3 → 4 taken 17 times.
17 const QString platform = QGuiApplication::platformName().toLower();
136
5/10
✓ Branch 6 → 7 taken 17 times.
✗ Branch 6 → 13 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 17 times.
✓ Branch 14 → 15 taken 17 times.
✗ Branch 14 → 16 not taken.
✓ Branch 16 → 17 taken 17 times.
✗ Branch 16 → 18 not taken.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 27 taken 17 times.
34 if (!platform.isEmpty() && platform != QStringLiteral("offscreen"))
137 ✗ return platform.startsWith(QStringLiteral("wayland"));
138 // Offscreen UI tests cannot load a second QPA plugin after QApplication was
139 // created. A wayland-test marker exercises the policy without pretending to
140 // provide compositor acceptance; production always uses platformName().
141
2/2
✓ Branch 27 → 28 taken 17 times.
✓ Branch 28 → 29 taken 17 times.
17 return qgetenv("QT_QPA_PLATFORM").toLower().startsWith("wayland");
142 17 }
143
144 #ifdef MAILJD_UNIT_TEST
145 2 void DesktopIntegration::setCapabilitiesForTest(
146 const std::optional<DesktopCapabilities> &capabilities) {
147 2 capabilityOverride = capabilities;
148 2 }
149
150 #endif
151