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.8% 127 / 0 / 134
Functions: 100.0% 9 / 0 / 9
Branches: 79.3% 203 / 0 / 256

presentation/ConflictCenter.cpp
Line Branch Exec Source
1 #include "ConflictCenter.h"
2
3 #include "QuickRulesBackend.h"
4 #include "app/core/CalendarOutbox.h"
5 #include "app/core/ContactOutbox.h"
6 #include "app/core/SettingsSyncSession.h"
7 #include "data/CalendarStore.h"
8 #include "data/ContactStore.h"
9 #include "data/VCardCodec.h"
10
11 #include <QDateTime>
12 #include <QLoggingCategory>
13 #include <QVariantMap>
14
15 Q_DECLARE_LOGGING_CATEGORY(lcConflict)
16
17 namespace {
18
19 74 QString kindOf(const QString &operation, bool serverDeleted, const QStringList &fields) {
20
2/2
✓ Branch 2 → 3 taken 18 times.
✓ Branch 2 → 8 taken 56 times.
74 if (serverDeleted)
21 18 return QStringLiteral("deletedOnServer");
22
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 16 taken 56 times.
56 if (operation == QLatin1String("delete"))
23 ✗ return QStringLiteral("deletedHere");
24
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 28 taken 56 times.
56 if (fields.contains(QStringLiteral("moved")))
25 ✗ return QStringLiteral("moved");
26
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 40 taken 56 times.
56 if (fields.contains(QStringLiteral("unreadable")))
27 ✗ return QStringLiteral("raw");
28 56 return QStringLiteral("changed");
29 }
30
31 197 QString iso(qint64 seconds) {
32
4/8
✓ Branch 2 → 3 taken 197 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 197 times.
✓ Branch 4 → 6 taken 197 times.
✓ Branch 7 → 8 taken 197 times.
✗ Branch 7 → 9 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 13 not taken.
394 return seconds > 0 ? QDateTime::fromSecsSinceEpoch(seconds).toString(Qt::ISODate) : QString();
33 }
34
35 } // namespace
36
37
1/1
✓ Branch 7 → 8 taken 797 times.
797 ConflictCenter::ConflictCenter(Deps deps, QObject *parent) : QObject(parent), m_deps(std::move(deps)) {
38
1/1
✓ Branch 8 → 9 taken 797 times.
797 m_refresh.setSingleShot(true);
39
1/1
✓ Branch 9 → 10 taken 797 times.
797 m_refresh.setInterval(0);
40
1/1
✓ Branch 10 → 11 taken 797 times.
797 connect(&m_refresh, &QTimer::timeout, this, &ConflictCenter::refresh);
41 797 }
42
43 797 void ConflictCenter::connectSources() {
44
4/4
✓ Branch 3 → 4 taken 796 times.
✓ Branch 3 → 6 taken 1 time.
✓ Branch 7 → 8 taken 795 times.
✓ Branch 7 → 11 taken 2 times.
797 if (CalendarOutbox *outbox = m_deps.calendarOutbox ? m_deps.calendarOutbox() : nullptr)
45
1/1
✓ Branch 8 → 9 taken 795 times.
795 connect(outbox, &CalendarOutbox::storeChanged, this, &ConflictCenter::scheduleRefresh, Qt::UniqueConnection);
46
4/4
✓ Branch 12 → 13 taken 796 times.
✓ Branch 12 → 15 taken 1 time.
✓ Branch 16 → 17 taken 795 times.
✓ Branch 16 → 20 taken 2 times.
797 if (ContactOutbox *outbox = m_deps.contactOutbox ? m_deps.contactOutbox() : nullptr)
47
1/1
✓ Branch 17 → 18 taken 795 times.
795 connect(outbox, &ContactOutbox::cardsChanged, this, &ConflictCenter::scheduleRefresh, Qt::UniqueConnection);
48
4/4
✓ Branch 21 → 22 taken 795 times.
✓ Branch 21 → 24 taken 2 times.
✓ Branch 25 → 26 taken 795 times.
✓ Branch 25 → 29 taken 2 times.
797 if (QuickRulesBackend *rules = m_deps.rules ? m_deps.rules() : nullptr)
49
1/1
✓ Branch 26 → 27 taken 795 times.
795 connect(rules, &QuickRulesBackend::conflictChanged, this, &ConflictCenter::scheduleRefresh, Qt::UniqueConnection);
50
4/4
✓ Branch 30 → 31 taken 796 times.
✓ Branch 30 → 33 taken 1 time.
✓ Branch 34 → 35 taken 795 times.
✓ Branch 34 → 38 taken 2 times.
797 if (SettingsSyncSession *session = m_deps.settings ? m_deps.settings() : nullptr)
51
1/1
✓ Branch 35 → 36 taken 795 times.
795 connect(session, &SettingsSyncSession::changed, this, &ConflictCenter::scheduleRefresh, Qt::UniqueConnection);
52 797 scheduleRefresh();
53 797 }
54
55 1922 void ConflictCenter::scheduleRefresh() { m_refresh.start(); }
56
57 29206 int ConflictCenter::countOf(const QString &area) const {
58 29206 int count = 0;
59
2/2
✓ Branch 24 → 4 taken 1389 times.
✓ Branch 24 → 25 taken 29206 times.
30595 for (const QVariant &entry : m_entries)
60
5/5
✓ Branch 5 → 6 taken 1389 times.
✓ Branch 10 → 11 taken 1389 times.
✓ Branch 11 → 12 taken 1389 times.
✓ Branch 13 → 14 taken 252 times.
✓ Branch 13 → 15 taken 1137 times.
2778 count += entry.toMap().value(QStringLiteral("area")).toString() == area ? 1 : 0;
61 29206 return count;
62 }
63
64 890 void ConflictCenter::refresh() {
65 890 QVariantList calendar, tasks, contacts, rules, settings;
66 890 QVariantList recent;
67
5/5
✓ Branch 3 → 4 taken 886 times.
✓ Branch 3 → 6 taken 4 times.
✓ Branch 4 → 5 taken 886 times.
✓ Branch 7 → 8 taken 886 times.
✓ Branch 7 → 220 taken 4 times.
890 if (CalendarStore *store = m_deps.calendarStore ? m_deps.calendarStore() : nullptr) {
68
5/5
✓ Branch 8 → 9 taken 886 times.
✓ Branch 9 → 10 taken 886 times.
✓ Branch 10 → 11 taken 886 times.
✓ Branch 143 → 12 taken 392 times.
✓ Branch 143 → 144 taken 886 times.
1278 for (const CalendarOutboxEntry &entry : store->outboxEntries()) {
69
2/2
✓ Branch 15 → 16 taken 323 times.
✓ Branch 15 → 17 taken 69 times.
392 if (entry.state != QLatin1String("conflict"))
70 323 continue;
71 69 const bool task = entry.componentType == QLatin1String("VTODO");
72 69 QString title;
73
2/2
✓ Branch 19 → 20 taken 29 times.
✓ Branch 19 → 27 taken 40 times.
69 if (task) {
74
2/3
✓ Branch 20 → 21 taken 29 times.
✓ Branch 22 → 23 taken 29 times.
✗ Branch 22 → 25 not taken.
29 if (const auto row = store->taskFor(entry.uid, entry.accountId, entry.calendarPath))
75 29 title = row->summary;
76
2/3
✓ Branch 27 → 28 taken 40 times.
✓ Branch 29 → 30 taken 40 times.
✗ Branch 29 → 32 not taken.
40 } else if (const auto row = store->eventFor(entry.uid, entry.accountId, entry.calendarPath)) {
77 40 title = row->summary;
78 40 }
79 138 const QVariantMap identity{{QStringLiteral("uid"), entry.uid},
80 138 {QStringLiteral("accountId"), entry.accountId},
81
2/4
✓ Branch 48 → 49 taken 207 times.
✓ Branch 48 → 50 taken 69 times.
✗ Branch 650 → 651 not taken.
✗ Branch 650 → 652 not taken.
345 {QStringLiteral("calendarPath"), entry.calendarPath}};
82 (task ? tasks : calendar)
83
9/13
✓ Branch 56 → 57 taken 29 times.
✓ Branch 56 → 58 taken 40 times.
✓ Branch 62 → 63 taken 29 times.
✓ Branch 62 → 66 taken 40 times.
✓ Branch 108 → 109 taken 69 times.
✓ Branch 132 → 133 taken 40 times.
✓ Branch 132 → 134 taken 29 times.
✓ Branch 134 → 135 taken 29 times.
✓ Branch 134 → 136 taken 40 times.
✗ Branch 735 → 736 not taken.
✗ Branch 735 → 737 not taken.
✗ Branch 739 → 740 not taken.
✗ Branch 739 → 741 not taken.
345 .append(QVariantMap{{QStringLiteral("area"), task ? QStringLiteral("tasks") : QStringLiteral("calendar")},
84
6/10
✓ Branch 73 → 74 taken 29 times.
✓ Branch 73 → 77 taken 40 times.
✓ Branch 125 → 126 taken 40 times.
✓ Branch 125 → 127 taken 29 times.
✓ Branch 127 → 128 taken 29 times.
✓ Branch 127 → 129 taken 40 times.
✗ Branch 718 → 719 not taken.
✗ Branch 718 → 720 not taken.
✗ Branch 722 → 723 not taken.
✗ Branch 722 → 724 not taken.
207 {QStringLiteral("domain"), task ? QStringLiteral("task") : QStringLiteral("event")},
85 138 {QStringLiteral("identity"), identity},
86 138 {QStringLiteral("title"), title},
87
3/3
✓ Branch 93 → 94 taken 18 times.
✓ Branch 93 → 98 taken 51 times.
✓ Branch 99 → 100 taken 69 times.
225 {QStringLiteral("kind"), kindOf(entry.operation, entry.serverIcal.isEmpty() &&
88
1/2
✓ Branch 96 → 97 taken 18 times.
✗ Branch 96 → 98 not taken.
87 entry.operation != QLatin1String("delete"),
89 69 entry.conflictFields)},
90
3/5
✓ Branch 104 → 105 taken 69 times.
✓ Branch 112 → 113 taken 414 times.
✓ Branch 112 → 114 taken 69 times.
✗ Branch 682 → 683 not taken.
✗ Branch 682 → 684 not taken.
552 {QStringLiteral("since"), iso(entry.created)}});
91 955 }
92
5/5
✓ Branch 145 → 146 taken 886 times.
✓ Branch 146 → 147 taken 886 times.
✓ Branch 147 → 148 taken 886 times.
✓ Branch 217 → 149 taken 116 times.
✓ Branch 217 → 218 taken 886 times.
1002 for (const ConflictHistory::Entry &history : store->conflictHistory(10))
93
1/1
✓ Branch 189 → 190 taken 116 times.
464 recent.append(QVariantMap{{QStringLiteral("store"), QStringLiteral("calendar")},
94 232 {QStringLiteral("id"), history.id},
95 232 {QStringLiteral("title"), history.title},
96 232 {QStringLiteral("keptSide"), history.keptSide},
97
2/4
✓ Branch 174 → 175 taken 40 times.
✓ Branch 174 → 178 taken 76 times.
✗ Branch 789 → 790 not taken.
✗ Branch 789 → 791 not taken.
348 {QStringLiteral("area"), history.component == QLatin1String("VTODO") ? QStringLiteral("tasks")
98
4/6
✓ Branch 199 → 200 taken 76 times.
✓ Branch 199 → 201 taken 40 times.
✓ Branch 201 → 202 taken 40 times.
✓ Branch 201 → 203 taken 76 times.
✗ Branch 785 → 786 not taken.
✗ Branch 785 → 787 not taken.
116 : QStringLiteral("calendar")},
99
3/5
✓ Branch 185 → 186 taken 116 times.
✓ Branch 193 → 194 taken 696 times.
✓ Branch 193 → 195 taken 116 times.
✗ Branch 771 → 772 not taken.
✗ Branch 771 → 773 not taken.
1930 {QStringLiteral("resolvedAt"), iso(history.resolvedAt)}});
100 }
101
5/5
✓ Branch 221 → 222 taken 886 times.
✓ Branch 221 → 224 taken 4 times.
✓ Branch 222 → 223 taken 886 times.
✓ Branch 225 → 226 taken 886 times.
✓ Branch 225 → 401 taken 4 times.
890 if (ContactStore *store = m_deps.contactStore ? m_deps.contactStore() : nullptr) {
102
5/5
✓ Branch 226 → 227 taken 886 times.
✓ Branch 227 → 228 taken 886 times.
✓ Branch 228 → 229 taken 886 times.
✓ Branch 333 → 230 taken 45 times.
✓ Branch 333 → 334 taken 886 times.
931 for (const ContactOutboxEntry &entry : store->outboxEntries()) {
103
2/2
✓ Branch 233 → 234 taken 40 times.
✓ Branch 233 → 235 taken 5 times.
45 if (entry.state != QLatin1String("conflict"))
104 40 continue;
105 5 QString title;
106
1/1
✓ Branch 235 → 236 taken 5 times.
5 ContactCard card;
107
1/1
✓ Branch 236 → 237 taken 5 times.
5 const auto stored = store->card(entry.bookId, entry.uid);
108
3/5
✓ Branch 238 → 239 taken 5 times.
✗ Branch 238 → 241 not taken.
✓ Branch 242 → 243 taken 5 times.
✓ Branch 243 → 244 taken 5 times.
✗ Branch 243 → 245 not taken.
5 if (VCardCodec::parse(stored ? stored->raw : entry.serverRaw, &card))
109 5 title = card.formattedName;
110
1/1
✓ Branch 295 → 296 taken 5 times.
5 contacts.append(QVariantMap{
111 15 {QStringLiteral("area"), QStringLiteral("contacts")},
112 15 {QStringLiteral("domain"), QStringLiteral("contact")},
113
2/4
✓ Branch 311 → 312 taken 10 times.
✓ Branch 311 → 313 taken 5 times.
✗ Branch 878 → 879 not taken.
✗ Branch 878 → 880 not taken.
30 {QStringLiteral("identity"), QVariantMap{{QStringLiteral("bookId"), entry.bookId}, {QStringLiteral("uid"), entry.uid}}},
114 10 {QStringLiteral("title"), title},
115 10 {QStringLiteral("kind"),
116
2/5
✗ Branch 280 → 281 not taken.
✓ Branch 280 → 285 taken 5 times.
✗ Branch 283 → 284 not taken.
✗ Branch 283 → 285 not taken.
✓ Branch 286 → 287 taken 5 times.
10 kindOf(entry.operation, entry.serverRaw.isEmpty() && entry.operation != QLatin1String("delete"),
117 5 entry.conflictFields)},
118
2/4
✓ Branch 299 → 300 taken 30 times.
✓ Branch 299 → 301 taken 5 times.
✗ Branch 847 → 848 not taken.
✗ Branch 847 → 849 not taken.
40 {QStringLiteral("since"), QString()}});
119 891 }
120
5/5
✓ Branch 335 → 336 taken 886 times.
✓ Branch 336 → 337 taken 886 times.
✓ Branch 337 → 338 taken 886 times.
✓ Branch 398 → 339 taken 12 times.
✓ Branch 398 → 399 taken 886 times.
898 for (const ConflictHistory::Entry &history : store->conflictHistory(10))
121
1/1
✓ Branch 373 → 374 taken 12 times.
48 recent.append(QVariantMap{{QStringLiteral("store"), QStringLiteral("contacts")},
122 24 {QStringLiteral("id"), history.id},
123 24 {QStringLiteral("title"), history.title},
124 24 {QStringLiteral("keptSide"), history.keptSide},
125 36 {QStringLiteral("area"), QStringLiteral("contacts")},
126
3/5
✓ Branch 369 → 370 taken 12 times.
✓ Branch 377 → 378 taken 72 times.
✓ Branch 377 → 379 taken 12 times.
✗ Branch 953 → 954 not taken.
✗ Branch 953 → 955 not taken.
994 {QStringLiteral("resolvedAt"), iso(history.resolvedAt)}});
127 }
128
9/9
✓ Branch 402 → 403 taken 883 times.
✓ Branch 402 → 405 taken 7 times.
✓ Branch 403 → 404 taken 883 times.
✓ Branch 406 → 407 taken 883 times.
✓ Branch 406 → 410 taken 7 times.
✓ Branch 408 → 409 taken 1 time.
✓ Branch 408 → 410 taken 882 times.
✓ Branch 411 → 412 taken 1 time.
✓ Branch 411 → 478 taken 889 times.
890 if (QuickRulesBackend *backend = m_deps.rules ? m_deps.rules() : nullptr; backend && backend->conflictActive())
129
1/1
✓ Branch 450 → 451 taken 1 time.
4 rules.append(QVariantMap{{QStringLiteral("area"), QStringLiteral("rules")},
130 3 {QStringLiteral("domain"), QStringLiteral("rules")},
131 2 {QStringLiteral("identity"), QVariantMap{}},
132
1/1
✓ Branch 434 → 435 taken 1 time.
2 {QStringLiteral("title"), tr("Rules")},
133 3 {QStringLiteral("kind"), QStringLiteral("changed")},
134
2/4
✓ Branch 454 → 455 taken 6 times.
✓ Branch 454 → 456 taken 1 time.
✗ Branch 1023 → 1024 not taken.
✗ Branch 1023 → 1025 not taken.
9 {QStringLiteral("since"), QString()}});
135
3/3
✓ Branch 479 → 480 taken 887 times.
✓ Branch 479 → 482 taken 3 times.
✓ Branch 480 → 481 taken 887 times.
890 if (SettingsSyncSession *session = m_deps.settings ? m_deps.settings() : nullptr;
136
8/8
✓ Branch 483 → 484 taken 887 times.
✓ Branch 483 → 489 taken 3 times.
✓ Branch 487 → 488 taken 2 times.
✓ Branch 487 → 489 taken 885 times.
✓ Branch 490 → 491 taken 887 times.
✓ Branch 490 → 492 taken 3 times.
✓ Branch 492 → 493 taken 2 times.
✓ Branch 492 → 559 taken 888 times.
890 session && session->state() == QLatin1String("conflict"))
137
1/1
✓ Branch 531 → 532 taken 2 times.
8 settings.append(QVariantMap{{QStringLiteral("area"), QStringLiteral("settings")},
138 6 {QStringLiteral("domain"), QStringLiteral("settings")},
139 4 {QStringLiteral("identity"), QVariantMap{}},
140
1/1
✓ Branch 515 → 516 taken 2 times.
4 {QStringLiteral("title"), tr("Synchronized settings")},
141 6 {QStringLiteral("kind"), QStringLiteral("changed")},
142
2/4
✓ Branch 535 → 536 taken 12 times.
✓ Branch 535 → 537 taken 2 times.
✗ Branch 1102 → 1103 not taken.
✗ Branch 1102 → 1104 not taken.
18 {QStringLiteral("since"), QString()}});
143
3/3
✓ Branch 559 → 560 taken 890 times.
✓ Branch 560 → 561 taken 890 times.
✓ Branch 561 → 562 taken 890 times.
890 std::sort(recent.begin(), recent.end(), [](const QVariant &a, const QVariant &b) {
144
6/6
✓ Branch 2 → 3 taken 166 times.
✓ Branch 7 → 8 taken 166 times.
✓ Branch 8 → 9 taken 166 times.
✓ Branch 9 → 10 taken 166 times.
✓ Branch 14 → 15 taken 166 times.
✓ Branch 15 → 16 taken 166 times.
498 return a.toMap().value(QStringLiteral("resolvedAt")).toString() > b.toMap().value(QStringLiteral("resolvedAt")).toString();
145 });
146
1/2
✗ Branch 565 → 563 not taken.
✓ Branch 565 → 566 taken 890 times.
890 while (recent.size() > 10)
147 ✗ recent.removeLast();
148
4/4
✓ Branch 566 → 567 taken 890 times.
✓ Branch 567 → 568 taken 890 times.
✓ Branch 568 → 569 taken 890 times.
✓ Branch 569 → 570 taken 890 times.
890 const QVariantList entries = calendar + tasks + contacts + rules + settings;
149
8/8
✓ Branch 573 → 574 taken 890 times.
✓ Branch 574 → 575 taken 841 times.
✓ Branch 574 → 578 taken 49 times.
✓ Branch 575 → 576 taken 841 times.
✓ Branch 576 → 577 taken 840 times.
✓ Branch 576 → 578 taken 1 time.
✓ Branch 579 → 580 taken 840 times.
✓ Branch 579 → 581 taken 50 times.
890 if (entries == m_entries && recent == m_recent)
150 840 return;
151
2/2
✓ Branch 583 → 584 taken 49 times.
✓ Branch 583 → 613 taken 1 time.
50 if (entries.size() != m_entries.size())
152
10/10
✓ Branch 584 → 585 taken 49 times.
✓ Branch 588 → 589 taken 49 times.
✓ Branch 589 → 590 taken 49 times.
✓ Branch 591 → 592 taken 49 times.
✓ Branch 592 → 593 taken 49 times.
✓ Branch 594 → 595 taken 49 times.
✓ Branch 595 → 596 taken 49 times.
✓ Branch 597 → 598 taken 49 times.
✓ Branch 611 → 586 taken 49 times.
✓ Branch 611 → 612 taken 49 times.
98 qCInfo(lcConflict) << "open conflicts:" << entries.size() << "(calendar" << calendar.size() << "tasks" << tasks.size()
153
7/7
✓ Branch 598 → 599 taken 49 times.
✓ Branch 600 → 601 taken 49 times.
✓ Branch 601 → 602 taken 49 times.
✓ Branch 603 → 604 taken 49 times.
✓ Branch 604 → 605 taken 49 times.
✓ Branch 606 → 607 taken 49 times.
✓ Branch 607 → 608 taken 49 times.
49 << "contacts" << contacts.size() << "rules" << rules.size() << "settings" << settings.size() << ")";
154 50 m_entries = entries;
155 50 m_recent = recent;
156
1/1
✓ Branch 615 → 616 taken 50 times.
50 emit changed();
157 7651 }
158
159 1 bool ConflictCenter::undo(const QString &store, qint64 id) {
160 1 bool ok = false;
161
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 13 not taken.
1 if (store == QLatin1String("calendar")) {
162
2/4
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 9 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 24 not taken.
1 if (CalendarOutbox *outbox = m_deps.calendarOutbox ? m_deps.calendarOutbox() : nullptr)
163 1 ok = outbox->restoreFromHistory(id);
164 ✗ } else if (store == QLatin1String("contacts")) {
165 ✗ if (ContactOutbox *outbox = m_deps.contactOutbox ? m_deps.contactOutbox() : nullptr)
166 ✗ ok = outbox->restoreFromHistory(id);
167 }
168 1 refresh();
169 1 return ok;
170 }
171