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: 100.0% 25 / 0 / 25
Functions: 100.0% 10 / 0 / 10
Branches: 64.3% 18 / 0 / 28

presentation/QuickDavPush.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QAbstractListModel>
4 #include <QObject>
5 #include <QPointer>
6 #include <QTimer>
7 #include <QVariantMap>
8 #include <functional>
9 #include <optional>
10
11 #include "app/core/DavPushCoordinator.h"
12
13 class CalendarSyncCoordinator;
14 class DavPushServiceTest;
15
16 // One derived row of the push status (SPRINT-96.md §5.2, design
17 // docs/design/sprint-96/davpush-ui.md §2). Pure value; built by
18 // QuickDavPush::deriveRow() from the separate state dimensions.
19 struct DavPushRow {
20 74 QString key; // calendarSelectionKey(accountId, path)
21 74 QString kind; // "calendar" or "addressbook"
22 74 QString accountId;
23 74 QString path;
24 74 QString displayName;
25 74 QString accountLabel;
26 74 bool automatic = true;
27 70 QString stateKey; // paused, offline, sync-error, conflict, interrupted, setup, checking,
28 // connecting, active, active-received, unsupported, off, never
29 56 QString stateText;
30 55 QString severity; // ok, info, warning, error, paused, neutral
31 55 int icon = 0; // MDI code point
32 55 QString detailText; // one sentence cause/next step
33
16/24
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 74 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 74 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 74 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 74 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 74 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 74 times.
✓ Branch 20 → 21 taken 4 times.
✓ Branch 20 → 22 taken 70 times.
✓ Branch 23 → 24 taken 14 times.
✓ Branch 23 → 25 taken 56 times.
✓ Branch 26 → 27 taken 1 time.
✓ Branch 26 → 28 taken 55 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 55 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 55 times.
✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 36 taken 53 times.
74 bool operator==(const DavPushRow &) const = default;
34 };
35
36 // Inputs of the derivation besides the coordinator status.
37 struct DavPushRowContext {
38 QString accountSyncError; // CalendarSyncStatus kind of the account ("" = ok)
39 int pendingWrites = 0; // outbox entries of the calendar
40 int conflicts = 0;
41 bool receiverConfigured = false;
42 bool pushEnabled = true;
43 int intervalMinutes = 15;
44 };
45
46 // Sprint 96 S96.4.1: list model of the push status per selected DAV
47 // calendar or address book (S96.6.3). Updates are incremental: changed rows emit dataChanged with
48 // their roles; only a changed set of calendars resets the model.
49 class QuickDavPushModel final : public QAbstractListModel {
50 Q_OBJECT
51 public:
52 enum Role {
53 KeyRole = Qt::UserRole + 1, AccountIdRole, PathRole, DisplayNameRole, AccountLabelRole, AutomaticRole,
54 StateKeyRole, StateTextRole, SeverityRole, IconRole, DetailTextRole, KindRole
55 };
56 using QAbstractListModel::QAbstractListModel;
57 int rowCount(const QModelIndex &parent = {}) const override;
58 QVariant data(const QModelIndex &index, int role) const override;
59 QHash<int, QByteArray> roleNames() const override;
60 void setRows(const QList<DavPushRow> &rows);
61 4189 const QList<DavPushRow> &rows() const { return m_rows; }
62
63 private:
64 QList<DavPushRow> m_rows;
65 };
66
67 // Sprint 96 S96.4.1–S96.4.4: backend.pim.push — the push status for the
68 // calendar/task sidebars, the DAV settings section and the details popup,
69 // plus the push service form (draft → test → save) and the actions with
70 // their scopes (§5.5). No network or XML logic; everything goes through
71 // DavPushCoordinator.
72 class QuickDavPush final : public QObject {
73 1011 Q_OBJECT
74 Q_PROPERTY(bool available READ available CONSTANT)
75 Q_PROPERTY(QAbstractItemModel *calendars READ calendars CONSTANT)
76 Q_PROPERTY(int revision READ revision NOTIFY changed)
77 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY changed)
78 Q_PROPERTY(bool serviceConfigured READ serviceConfigured NOTIFY changed)
79 Q_PROPERTY(QString serviceKind READ serviceKind NOTIFY changed)
80 Q_PROPERTY(QString serviceServer READ serviceServer NOTIFY changed)
81 Q_PROPERTY(bool serviceHasToken READ serviceHasToken NOTIFY changed)
82 Q_PROPERTY(QString publicServer READ publicServer CONSTANT)
83 Q_PROPERTY(QString testState READ testState NOTIFY testChanged)
84 Q_PROPERTY(QString testMessage READ testMessage NOTIFY testChanged)
85 Q_PROPERTY(QString summaryText READ summaryText NOTIFY changed)
86 Q_PROPERTY(QVariantList accounts READ accounts NOTIFY changed)
87 // DAVPUSH-KUP: a UnifiedPush D-Bus distributor (KUnifiedPush) on the bus.
88 Q_PROPERTY(bool systemServiceDetected READ systemServiceDetected NOTIFY changed)
89 Q_PROPERTY(QString systemServiceName READ systemServiceName NOTIFY changed)
90 Q_PROPERTY(bool useSystemService READ useSystemService WRITE setUseSystemService NOTIFY changed)
91 // True when push currently runs through the system service.
92 Q_PROPERTY(bool systemServiceActive READ systemServiceActive NOTIFY changed)
93 public:
94 using Clock = std::function<qint64()>; // epoch seconds
95 QuickDavPush(DavPushCoordinator *coordinator, CalendarSyncCoordinator *calendar, QObject *parent = nullptr);
96 ~QuickDavPush() override;
97
98
2/4
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 8 not taken.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 8 not taken.
1 bool available() const { return m_coordinator && m_coordinator->isOpen(); }
99 40 QAbstractItemModel *calendars() { return &m_model; }
100 3064 int revision() const { return m_revision; }
101 bool enabled() const;
102 void setEnabled(bool enabled);
103 bool serviceConfigured() const;
104 QString serviceKind() const;
105 QString serviceServer() const;
106 bool serviceHasToken() const;
107 QString publicServer() const;
108 104 QString testState() const { return m_testState; }
109 42 QString testMessage() const { return m_testMessage; }
110 QString summaryText() const;
111 QVariantList accounts() const;
112 bool systemServiceDetected() const;
113 QString systemServiceName() const;
114 bool useSystemService() const;
115 void setUseSystemService(bool use);
116 bool systemServiceActive() const;
117
118 Q_INVOKABLE void testService(const QString &kind, const QString &server, const QString &token);
119 Q_INVOKABLE void cancelTest();
120 // {ok, error}; the draft becomes the active service only here.
121 Q_INVOKABLE QVariantMap saveService(const QString &kind, const QString &server, const QString &token);
122 Q_INVOKABLE void removeService();
123 Q_INVOKABLE bool setAutomatic(const QString &key, bool automatic);
124 Q_INVOKABLE void syncNow(const QString &key);
125 Q_INVOKABLE void detectAgain(const QString &key);
126 Q_INVOKABLE void reconnect(const QString &accountId);
127 Q_INVOKABLE bool resetStatistics(const QString &key);
128 Q_INVOKABLE bool copyDiagnostics();
129 // Sidebar: {stateKey, stateText, severity, icon, accessibleName} ("" key
130 // when the calendar is no DAV calendar). `revision` re-evaluates bindings.
131 Q_INVOKABLE QVariantMap statusFor(const QString &key, int revision = 0) const;
132 // Smart lists: "Push active for 3 of 5 calendars" for the given keys.
133 Q_INVOKABLE QString summaryFor(const QVariantList &keys, int revision = 0) const;
134 Q_INVOKABLE QVariantMap details(const QString &key, int revision = 0) const;
135
136 static DavPushRow deriveRow(const DavPushCollectionStatus &status, const DavPushRowContext &context);
137 5 void setClock(Clock clock) { m_clock = std::move(clock); }
138 // Test/capture seam: the status source (default: the coordinator).
139 7 void setStatusProvider(std::function<QList<DavPushCollectionStatus>()> provider) {
140 7 m_statusProvider = std::move(provider);
141 7 refresh();
142 7 }
143 void refresh();
144
145 signals:
146 void changed();
147 void testChanged();
148 // The redacted report that was copied to the clipboard.
149 void diagnosticsReady(const QString &text);
150
151 private:
152 qint64 now() const;
153 QString timeText(qint64 epochSeconds) const;
154 QString relativeText(qint64 epochSeconds) const;
155 std::optional<DavPushCollectionStatus> statusOf(const QString &key) const;
156 QVariantMap statisticsFor(const DavPushCollectionStatus &status) const;
157 DavPushRowContext contextFor(const DavPushCollectionStatus &status) const;
158
159 QPointer<DavPushCoordinator> m_coordinator;
160 QPointer<CalendarSyncCoordinator> m_calendar;
161 QuickDavPushModel m_model;
162 QList<DavPushCollectionStatus> m_statuses;
163 QTimer m_coalesce;
164 QTimer m_age;
165 DavPushServiceTest *m_test = nullptr;
166 QString m_testState = QStringLiteral("idle");
167 QString m_testMessage;
168 int m_revision = 0;
169 Clock m_clock;
170 std::function<QList<DavPushCollectionStatus>()> m_statusProvider;
171 };
172