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% 106 / 0 / 106
Functions: 100.0% 10 / 0 / 10
Branches: 84.4% 211 / 0 / 250

presentation/AccountOverview.cpp
Line Branch Exec Source
1 #include "AccountOverview.h"
2 #include <QUrl>
3 #include <QVariantMap>
4
5 namespace {
6 8170 QVariantMap service(const QString &state, const QString &text, const QString &detail = {}) {
7
2/4
✓ Branch 16 → 17 taken 24510 times.
✓ Branch 16 → 18 taken 8170 times.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
57190 return {{QStringLiteral("state"), state}, {QStringLiteral("text"), text}, {QStringLiteral("detail"), detail}};
8 32680 }
9 9420 bool needsAttention(const QVariantMap &service) {
10
2/2
✓ Branch 6 → 7 taken 9420 times.
✓ Branch 7 → 8 taken 9420 times.
18840 const QString state = service.value(QStringLiteral("state")).toString();
11
4/4
✓ Branch 17 → 18 taken 9387 times.
✓ Branch 17 → 24 taken 1 time.
✓ Branch 20 → 21 taken 9020 times.
✓ Branch 20 → 24 taken 367 times.
28195 return state == QLatin1String("needs-password") || state == QLatin1String("error") ||
12
4/4
✓ Branch 14 → 15 taken 9388 times.
✓ Branch 14 → 24 taken 32 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 9019 times.
37615 state == QLatin1String("choose") || state == QLatin1String("new");
13 9420 }
14 625 QString davLabel(const AccountOverview::Dav &dav) {
15
2/2
✓ Branch 2 → 3 taken 625 times.
✓ Branch 4 → 5 taken 625 times.
1250 const QString host = QUrl(dav.serverUrl).host();
16
6/7
✓ Branch 7 → 8 taken 625 times.
✓ Branch 8 → 9 taken 624 times.
✓ Branch 8 → 11 taken 1 time.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 624 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 624 times.
625 if (dav.username.contains('@') || host.isEmpty()) return dav.username;
17
2/2
✓ Branch 17 → 18 taken 624 times.
✓ Branch 18 → 19 taken 624 times.
624 return dav.username + QLatin1Char('@') + host;
18 625 }
19 } // namespace
20
21 1858 QString AccountOverview::baseDomain(const QString &host) {
22
2/2
✓ Branch 2 → 3 taken 1858 times.
✓ Branch 5 → 6 taken 1858 times.
1858 const QStringList labels = host.toLower().split('.', Qt::SkipEmptyParts);
23
3/3
✓ Branch 8 → 9 taken 771 times.
✓ Branch 8 → 12 taken 1087 times.
✓ Branch 10 → 11 taken 771 times.
1858 if (labels.size() <= 2) return labels.join('.');
24 // Two-label public suffixes common for mail providers ("co.uk", "com.au").
25
2/2
✓ Branch 13 → 14 taken 1087 times.
✓ Branch 15 → 16 taken 1087 times.
1087 const QString last2 = labels.mid(labels.size() - 2).join('.');
26
5/10
✓ Branch 17 → 18 taken 7 times.
✓ Branch 17 → 33 taken 1080 times.
✓ Branch 19 → 20 taken 7 times.
✗ Branch 19 → 33 not taken.
✓ Branch 30 → 31 taken 42 times.
✓ Branch 30 → 32 taken 7 times.
✗ Branch 62 → 63 not taken.
✗ Branch 62 → 64 not taken.
✗ Branch 71 → 72 not taken.
✗ Branch 71 → 73 not taken.
1136 static const QStringList twoLabelSuffixes = {"co.uk", "org.uk", "com.au", "co.nz", "co.jp", "com.br"};
27
7/8
✓ Branch 34 → 35 taken 1 time.
✓ Branch 34 → 38 taken 1086 times.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 38 not taken.
✓ Branch 39 → 40 taken 1 time.
✓ Branch 39 → 46 taken 1086 times.
✓ Branch 41 → 42 taken 1 time.
✓ Branch 43 → 44 taken 1 time.
1087 if (twoLabelSuffixes.contains(last2) && labels.size() >= 3) return labels.mid(labels.size() - 3).join('.');
28 1086 return last2;
29 1865 }
30
31 627 QString AccountOverview::linkSuggestion(const Dav &dav, const QList<Mail> &mails) {
32
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 627 times.
627 if (!dav.mailAccountId.isEmpty()) return {};
33
3/3
✓ Branch 5 → 6 taken 627 times.
✓ Branch 7 → 8 taken 627 times.
✓ Branch 8 → 9 taken 627 times.
1254 const QString davDomain = baseDomain(QUrl(dav.serverUrl).host());
34
2/2
✓ Branch 46 → 13 taken 623 times.
✓ Branch 46 → 47 taken 626 times.
1249 for (const auto &mail : mails) {
35
3/4
✓ Branch 15 → 16 taken 623 times.
✗ Branch 15 → 21 not taken.
✓ Branch 17 → 18 taken 621 times.
✓ Branch 17 → 20 taken 2 times.
1867 const bool sameLogin = !dav.username.isEmpty() &&
36
1/2
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 621 times.
1244 (dav.username.compare(mail.imapUsername, Qt::CaseInsensitive) == 0 ||
37 621 dav.username.compare(mail.email, Qt::CaseInsensitive) == 0);
38
3/4
✓ Branch 23 → 24 taken 623 times.
✗ Branch 23 → 34 not taken.
✓ Branch 26 → 27 taken 606 times.
✓ Branch 26 → 33 taken 17 times.
1852 const bool sameDomain = !davDomain.isEmpty() &&
39
10/17
✓ Branch 24 → 25 taken 623 times.
✓ Branch 29 → 30 taken 606 times.
✓ Branch 30 → 31 taken 606 times.
✓ Branch 32 → 33 taken 441 times.
✓ Branch 32 → 34 taken 165 times.
✓ Branch 35 → 36 taken 606 times.
✓ Branch 35 → 37 taken 17 times.
✓ Branch 37 → 38 taken 606 times.
✓ Branch 37 → 39 taken 17 times.
✓ Branch 39 → 40 taken 623 times.
✗ Branch 39 → 41 not taken.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 61 not taken.
✗ Branch 63 → 64 not taken.
✗ Branch 63 → 65 not taken.
✗ Branch 69 → 70 not taken.
✗ Branch 69 → 71 not taken.
1852 (davDomain == baseDomain(mail.imapHost) || davDomain == baseDomain(mail.email.section('@', 1)));
40
4/4
✓ Branch 41 → 42 taken 2 times.
✓ Branch 41 → 44 taken 621 times.
✓ Branch 42 → 43 taken 1 time.
✓ Branch 42 → 44 taken 1 time.
623 if (sameLogin && sameDomain) return mail.id;
41 }
42 626 return {};
43 627 }
44
45 2515 QVariantMap AccountOverview::mailService(const Mail &mail, const Active &active) {
46
4/4
✓ Branch 3 → 4 taken 60 times.
✓ Branch 3 → 16 taken 2455 times.
✓ Branch 5 → 6 taken 60 times.
✓ Branch 9 → 10 taken 60 times.
2575 if (mail.id != active.accountId) return service(QStringLiteral("idle"), tr("Not active"));
47
4/4
✓ Branch 18 → 19 taken 11 times.
✓ Branch 18 → 31 taken 2444 times.
✓ Branch 20 → 21 taken 11 times.
✓ Branch 24 → 25 taken 11 times.
2466 if (active.mailState == QLatin1String("connected")) return service(QStringLiteral("connected"), tr("Connected"));
48
4/4
✓ Branch 33 → 34 taken 10 times.
✓ Branch 33 → 46 taken 2434 times.
✓ Branch 35 → 36 taken 10 times.
✓ Branch 39 → 40 taken 10 times.
2454 if (active.mailState == QLatin1String("connecting")) return service(QStringLiteral("synchronizing"), tr("Connecting"));
49
2/2
✓ Branch 48 → 49 taken 1 time.
✓ Branch 48 → 59 taken 2433 times.
2434 if (active.mailState == QLatin1String("needs-password"))
50
2/2
✓ Branch 49 → 50 taken 1 time.
✓ Branch 53 → 54 taken 1 time.
2 return service(QStringLiteral("needs-password"), tr("Needs password"), active.mailError);
51
1/4
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 72 taken 2433 times.
✗ Branch 62 → 63 not taken.
✗ Branch 66 → 67 not taken.
2433 if (active.mailState == QLatin1String("error")) return service(QStringLiteral("error"), tr("Error"), active.mailError);
52
2/2
✓ Branch 73 → 74 taken 2433 times.
✓ Branch 77 → 78 taken 2433 times.
4866 return service(QStringLiteral("offline"), tr("Offline"));
53 }
54
55 2515 QVariantMap AccountOverview::rulesService(const Mail &mail, const Active &active) {
56
4/4
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 17 taken 2514 times.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 10 → 11 taken 1 time.
2516 if (mail.sieveMode == QLatin1String("off")) return service(QStringLiteral("off"), tr("Off"));
57
2/2
✓ Branch 18 → 19 taken 59 times.
✓ Branch 18 → 35 taken 2455 times.
2514 if (mail.id != active.accountId)
58
5/5
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 24 taken 58 times.
✓ Branch 23 → 25 taken 1 time.
✓ Branch 24 → 25 taken 58 times.
✓ Branch 28 → 29 taken 59 times.
118 return service(QStringLiteral("idle"), mail.sieveMode == QLatin1String("manual") ? tr("Manual") : tr("Automatic"));
59
2/2
✓ Branch 37 → 38 taken 105 times.
✓ Branch 37 → 62 taken 2350 times.
2455 if (active.rulesState == QLatin1String("available")) {
60
1/1
✓ Branch 38 → 39 taken 105 times.
105 QString text = tr("%n rules on", "", active.enabledRules);
61
5/5
✓ Branch 39 → 40 taken 6 times.
✓ Branch 39 → 51 taken 99 times.
✓ Branch 40 → 41 taken 6 times.
✓ Branch 44 → 45 taken 6 times.
✓ Branch 45 → 46 taken 6 times.
111 if (active.vacation) text += QStringLiteral(" · ") + tr("Out of office");
62
1/1
✓ Branch 55 → 56 taken 105 times.
210 return service(QStringLiteral("connected"), text);
63 105 }
64
4/4
✓ Branch 64 → 65 taken 71 times.
✓ Branch 64 → 77 taken 2279 times.
✓ Branch 66 → 67 taken 71 times.
✓ Branch 70 → 71 taken 71 times.
2421 if (active.rulesState == QLatin1String("checking")) return service(QStringLiteral("synchronizing"), tr("Checking"));
65
4/4
✓ Branch 79 → 80 taken 146 times.
✓ Branch 79 → 92 taken 2133 times.
✓ Branch 81 → 82 taken 146 times.
✓ Branch 85 → 86 taken 146 times.
2425 if (active.rulesState == QLatin1String("unavailable")) return service(QStringLiteral("off"), tr("Not available"));
66
1/4
✗ Branch 94 → 95 not taken.
✓ Branch 94 → 107 taken 2133 times.
✗ Branch 96 → 97 not taken.
✗ Branch 100 → 101 not taken.
2133 if (active.rulesState == QLatin1String("disabled")) return service(QStringLiteral("off"), tr("Off"));
67
2/2
✓ Branch 108 → 109 taken 2133 times.
✓ Branch 112 → 113 taken 2133 times.
4266 return service(QStringLiteral("idle"), tr("Automatic"));
68 }
69
70 3140 QVariantMap AccountOverview::davService(const Dav *dav) {
71
4/4
✓ Branch 2 → 3 taken 2507 times.
✓ Branch 2 → 15 taken 633 times.
✓ Branch 4 → 5 taken 2507 times.
✓ Branch 8 → 9 taken 2507 times.
5647 if (!dav) return service(QStringLiteral("off"), tr("Not set up"));
72
3/4
✓ Branch 15 → 16 taken 633 times.
✗ Branch 15 → 17 not taken.
✓ Branch 16 → 17 taken 31 times.
✓ Branch 16 → 27 taken 602 times.
633 if (dav->requiresAuthorization || dav->needsCredentials)
73
2/2
✓ Branch 17 → 18 taken 31 times.
✓ Branch 21 → 22 taken 31 times.
62 return service(QStringLiteral("needs-password"), tr("Needs password"), dav->error);
74
4/4
✓ Branch 29 → 30 taken 1 time.
✓ Branch 29 → 40 taken 601 times.
✓ Branch 30 → 31 taken 1 time.
✓ Branch 34 → 35 taken 1 time.
603 if (dav->state == QLatin1String("error")) return service(QStringLiteral("error"), tr("Error"), dav->error);
75
4/4
✓ Branch 40 → 41 taken 367 times.
✓ Branch 40 → 53 taken 234 times.
✓ Branch 42 → 43 taken 367 times.
✓ Branch 46 → 47 taken 367 times.
968 if (dav->calendars + dav->books == 0) return service(QStringLiteral("choose"), tr("Nothing chosen"));
76
1/4
✗ Branch 55 → 56 not taken.
✓ Branch 55 → 68 taken 234 times.
✗ Branch 57 → 58 not taken.
✗ Branch 61 → 62 not taken.
234 if (dav->state == QLatin1String("running")) return service(QStringLiteral("synchronizing"), tr("Synchronizing"));
77 // D-22: offered, never added automatically — the account asks for a look.
78
4/4
✓ Branch 68 → 69 taken 1 time.
✓ Branch 68 → 81 taken 233 times.
✓ Branch 70 → 71 taken 1 time.
✓ Branch 74 → 75 taken 1 time.
235 if (dav->fresh > 0) return service(QStringLiteral("new"), tr("%n new on the server", "", dav->fresh));
79 932 return service(QStringLiteral("connected"),
80
5/5
✓ Branch 82 → 83 taken 233 times.
✓ Branch 86 → 87 taken 233 times.
✓ Branch 87 → 88 taken 233 times.
✓ Branch 88 → 89 taken 233 times.
✓ Branch 92 → 93 taken 233 times.
932 tr("%n calendars", "", dav->calendars) + QStringLiteral(", ") + tr("%n address books", "", dav->books));
81 }
82
83 2484 QVariantList AccountOverview::build(const QList<Mail> &mails, const QList<Dav> &davs, const Active &active) {
84 2484 QVariantList result;
85 3140 const auto finish = [&result](QVariantMap entry) {
86 3140 QStringList attention;
87 3140 QString action, actionTarget;
88
2/2
✓ Branch 94 → 4 taken 9420 times.
✓ Branch 94 → 95 taken 3140 times.
12560 for (const char *key : {"mail", "rules", "calendars"}) {
89
3/3
✓ Branch 6 → 7 taken 9420 times.
✓ Branch 7 → 8 taken 9420 times.
✓ Branch 8 → 9 taken 9420 times.
9420 const QVariantMap item = entry.value(QLatin1String(key)).toMap();
90
3/3
✓ Branch 12 → 13 taken 9420 times.
✓ Branch 13 → 14 taken 9019 times.
✓ Branch 13 → 15 taken 401 times.
9420 if (!needsAttention(item)) continue;
91
3/3
✓ Branch 19 → 20 taken 401 times.
✓ Branch 20 → 21 taken 401 times.
✓ Branch 21 → 22 taken 401 times.
802 attention << item.value(QStringLiteral("text")).toString();
92
1/2
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 401 times.
401 if (!action.isEmpty()) continue;
93
2/2
✓ Branch 35 → 36 taken 401 times.
✓ Branch 36 → 37 taken 401 times.
802 const bool password = item.value(QStringLiteral("state")).toString() == QLatin1String("needs-password");
94
6/6
✓ Branch 43 → 44 taken 32 times.
✓ Branch 43 → 47 taken 369 times.
✓ Branch 52 → 53 taken 369 times.
✓ Branch 52 → 54 taken 32 times.
✓ Branch 54 → 55 taken 32 times.
✓ Branch 54 → 56 taken 369 times.
802 action = password ? QStringLiteral("password") : QStringLiteral("calendars");
95
3/3
✓ Branch 70 → 71 taken 401 times.
✓ Branch 71 → 72 taken 401 times.
✓ Branch 72 → 73 taken 401 times.
2005 actionTarget = QStringLiteral("accounts/%1/%2").arg(entry.value(QStringLiteral("id")).toString(),
96
6/10
✓ Branch 59 → 60 taken 32 times.
✓ Branch 59 → 63 taken 369 times.
✓ Branch 81 → 82 taken 369 times.
✓ Branch 81 → 83 taken 32 times.
✓ Branch 83 → 84 taken 32 times.
✓ Branch 83 → 85 taken 369 times.
✗ Branch 198 → 199 not taken.
✗ Branch 198 → 200 not taken.
✗ Branch 202 → 203 not taken.
✗ Branch 202 → 204 not taken.
1604 password ? QStringLiteral("password") : QStringLiteral("calendars"));
97 9420 }
98
1/1
✓ Branch 100 → 101 taken 3140 times.
6280 entry.insert(QStringLiteral("attention"), !attention.isEmpty());
99
2/2
✓ Branch 107 → 108 taken 3140 times.
✓ Branch 112 → 113 taken 3140 times.
6280 entry.insert(QStringLiteral("attentionText"), attention.join(QStringLiteral(" · ")));
100
1/1
✓ Branch 123 → 124 taken 3140 times.
6280 entry.insert(QStringLiteral("action"), action);
101
1/1
✓ Branch 131 → 132 taken 3140 times.
6280 entry.insert(QStringLiteral("actionTarget"), actionTarget);
102
1/1
✓ Branch 136 → 137 taken 3140 times.
3140 result.append(entry);
103 3140 };
104 2484 QStringList linked;
105
2/2
✓ Branch 104 → 4 taken 2515 times.
✓ Branch 104 → 105 taken 2484 times.
4999 for (const auto &mail : mails) {
106 2515 const Dav *dav = nullptr;
107
2/2
✓ Branch 13 → 7 taken 630 times.
✓ Branch 13 → 14 taken 2507 times.
3137 for (const auto &candidate : davs)
108
2/2
✓ Branch 9 → 10 taken 8 times.
✓ Branch 9 → 11 taken 622 times.
630 if (candidate.mailAccountId == mail.id) { dav = &candidate; break; }
109
3/3
✓ Branch 14 → 15 taken 8 times.
✓ Branch 14 → 16 taken 2507 times.
✓ Branch 15 → 16 taken 8 times.
2515 if (dav) linked << dav->id;
110
3/5
✓ Branch 70 → 71 taken 2515 times.
✓ Branch 73 → 74 taken 25150 times.
✓ Branch 73 → 75 taken 2515 times.
✗ Branch 197 → 198 not taken.
✗ Branch 197 → 199 not taken.
37725 finish({{QStringLiteral("id"), mail.id}, {QStringLiteral("kind"), QStringLiteral("mail")},
111 7545 {QStringLiteral("address"), mail.email}, {QStringLiteral("name"), mail.name},
112
2/2
✓ Branch 43 → 44 taken 8 times.
✓ Branch 43 → 45 taken 2507 times.
7545 {QStringLiteral("active"), mail.id == active.accountId}, {QStringLiteral("davId"), dav ? dav->id : QString()},
113
2/2
✓ Branch 50 → 51 taken 8 times.
✓ Branch 50 → 52 taken 2507 times.
5030 {QStringLiteral("davServer"), dav ? dav->serverUrl : QString()},
114
2/2
✓ Branch 57 → 58 taken 2515 times.
✓ Branch 62 → 63 taken 2515 times.
7545 {QStringLiteral("mail"), mailService(mail, active)}, {QStringLiteral("rules"), rulesService(mail, active)},
115
1/1
✓ Branch 67 → 68 taken 2515 times.
5030 {QStringLiteral("calendars"), davService(dav)}});
116 }
117
2/2
✓ Branch 190 → 107 taken 633 times.
✓ Branch 190 → 191 taken 2484 times.
3117 for (const auto &dav : davs) {
118
2/2
✓ Branch 109 → 110 taken 8 times.
✓ Branch 109 → 111 taken 625 times.
633 if (linked.contains(dav.id)) continue;
119
3/5
✓ Branch 157 → 158 taken 625 times.
✓ Branch 160 → 161 taken 5625 times.
✓ Branch 160 → 162 taken 625 times.
✗ Branch 293 → 294 not taken.
✗ Branch 293 → 295 not taken.
8750 finish({{QStringLiteral("id"), dav.id}, {QStringLiteral("kind"), QStringLiteral("dav")},
120
3/3
✓ Branch 125 → 126 taken 625 times.
✓ Branch 130 → 131 taken 625 times.
✓ Branch 132 → 133 taken 625 times.
2500 {QStringLiteral("address"), davLabel(dav)}, {QStringLiteral("name"), QUrl(dav.serverUrl).host()},
121 3125 {QStringLiteral("active"), false}, {QStringLiteral("davId"), dav.id}, {QStringLiteral("davServer"), dav.serverUrl},
122
1/1
✓ Branch 149 → 150 taken 625 times.
1250 {QStringLiteral("suggestion"), linkSuggestion(dav, mails)},
123
1/1
✓ Branch 154 → 155 taken 625 times.
1250 {QStringLiteral("calendars"), davService(&dav)}});
124 }
125 2484 return result;
126 37024 }
127