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: 93.3% 42 / 0 / 45
Functions: 100.0% 6 / 0 / 6
Branches: 89.3% 67 / 0 / 75

quick/ExternalWhitelistModel.cpp
Line Branch Exec Source
1 #include "ExternalWhitelistModel.h"
2
3 #include "data/MailCache.h"
4 #include "util/HostMatch.h"
5
6 21 QString normalizeWhitelistDomain(const QString &input) {
7
2/2
✓ Branch 2 → 3 taken 21 times.
✓ Branch 3 → 4 taken 21 times.
21 QString domain = input.trimmed().toLower();
8
4/4
✓ Branch 6 → 7 taken 1 time.
✓ Branch 8 → 9 taken 22 times.
✓ Branch 9 → 6 taken 1 time.
✓ Branch 9 → 10 taken 21 times.
22 while (domain.endsWith(u'.')) domain.chop(1);
9
6/6
✓ Branch 11 → 12 taken 19 times.
✓ Branch 11 → 14 taken 2 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 18 times.
✓ Branch 16 → 17 taken 3 times.
✓ Branch 16 → 18 taken 18 times.
21 if (domain.isEmpty() || domain.size() > 253) return {};
10 // Hostname characters only: letters, digits, hyphen, dots and IDN code
11 // points. Separators, schemes, paths, credentials or whitespace cannot be
12 // a request host and are rejected instead of being stored as dead entries.
13
4/4
✓ Branch 18 → 19 taken 18 times.
✓ Branch 19 → 20 taken 18 times.
✓ Branch 34 → 21 taken 213 times.
✓ Branch 34 → 35 taken 11 times.
224 for (const QChar &character : domain) {
14 213 const char16_t code = character.unicode();
15
4/4
✓ Branch 23 → 24 taken 2 times.
✓ Branch 23 → 29 taken 173 times.
✓ Branch 24 → 25 taken 16 times.
✓ Branch 24 → 26 taken 24 times.
213 const bool allowed = (code >= u'a' && code <= u'z') ||
16
10/10
✓ Branch 22 → 23 taken 175 times.
✓ Branch 22 → 24 taken 38 times.
✓ Branch 25 → 26 taken 4 times.
✓ Branch 25 → 29 taken 12 times.
✓ Branch 26 → 27 taken 10 times.
✓ Branch 26 → 29 taken 18 times.
✓ Branch 27 → 28 taken 9 times.
✓ Branch 27 → 29 taken 1 time.
✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 30 taken 7 times.
426 (code >= u'0' && code <= u'9') || code == u'.' || code == u'-' ||
17 code >= 0x80;
18
2/2
✓ Branch 31 → 32 taken 7 times.
✓ Branch 31 → 33 taken 206 times.
213 if (!allowed) return {};
19 }
20
7/7
✓ Branch 36 → 37 taken 11 times.
✓ Branch 37 → 38 taken 10 times.
✓ Branch 37 → 49 taken 1 time.
✓ Branch 48 → 49 taken 1 time.
✓ Branch 48 → 50 taken 9 times.
✓ Branch 51 → 52 taken 2 times.
✓ Branch 51 → 53 taken 9 times.
21 if (domain.startsWith(u'.') || domain.contains(u"..")) return {};
21 // S106-363: what can never match a request host (a label over 63, a code
22 // point without an ACE form) is refused, as the header documents —
23 // HostMatch compares canonical names only.
24
3/3
✓ Branch 53 → 54 taken 9 times.
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 58 taken 7 times.
9 if (HostMatch::canonicalName(domain).isEmpty()) return {};
25 7 return domain;
26 21 }
27
28 797 ExternalWhitelistModel::ExternalWhitelistModel(MailCache &cache, QObject *parent)
29 797 : QAbstractListModel(parent), m_cache(cache) {
30
1/1
✓ Branch 4 → 5 taken 797 times.
797 connect(&cache, &MailCache::whitelistChanged, this, &ExternalWhitelistModel::refresh);
31
1/1
✓ Branch 6 → 7 taken 797 times.
797 refresh();
32 797 }
33
34 49 int ExternalWhitelistModel::rowCount(const QModelIndex &parent) const {
35
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 49 times.
49 return parent.isValid() ? 0 : m_entries.size();
36 }
37
38 8 QVariant ExternalWhitelistModel::data(const QModelIndex &index, int role) const {
39
4/8
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 9 not taken.
✓ Branch 5 → 6 taken 8 times.
✗ Branch 5 → 9 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 8 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 8 times.
8 if (!index.isValid() || index.row() < 0 || index.row() >= m_entries.size())
40 ✗ return {};
41 8 const auto &entry = m_entries[index.row()];
42
4/5
✓ Branch 15 → 16 taken 3 times.
✓ Branch 15 → 17 taken 1 time.
✓ Branch 15 → 18 taken 3 times.
✓ Branch 15 → 19 taken 1 time.
✗ Branch 15 → 20 not taken.
8 switch (role) {
43 3 case EntryId: return entry.id;
44 1 case EntryType: return entry.type;
45 3 case EntryValue: return entry.value;
46 1 case EntryAdded: return entry.createdAt;
47 ✗ default: return {};
48 }
49 }
50
51 7 QHash<int, QByteArray> ExternalWhitelistModel::roleNames() const {
52 ✗ return {{EntryId, "entryId"}, {EntryType, "entryType"},
53
2/4
✓ Branch 8 → 9 taken 28 times.
✓ Branch 8 → 10 taken 7 times.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
35 {EntryValue, "entryValue"}, {EntryAdded, "entryAdded"}};
54 7 }
55
56 807 void ExternalWhitelistModel::refresh() {
57
1/1
✓ Branch 3 → 4 taken 807 times.
807 QList<WhitelistEntry> all = m_cache.allowlist().whitelistEntries();
58 807 QList<WhitelistEntry> domains;
59
1/1
✓ Branch 5 → 6 taken 807 times.
807 domains.reserve(all.size());
60
4/4
✓ Branch 6 → 7 taken 807 times.
✓ Branch 7 → 8 taken 807 times.
✓ Branch 17 → 9 taken 12 times.
✓ Branch 17 → 18 taken 807 times.
819 for (auto &entry : all) {
61
3/3
✓ Branch 12 → 13 taken 10 times.
✓ Branch 12 → 15 taken 2 times.
✓ Branch 14 → 15 taken 10 times.
12 if (entry.type == QLatin1String("domain")) domains.append(std::move(entry));
62 }
63
1/1
✓ Branch 18 → 19 taken 807 times.
807 beginResetModel();
64 807 m_entries = std::move(domains);
65
1/1
✓ Branch 21 → 22 taken 807 times.
807 endResetModel();
66
1/1
✓ Branch 22 → 23 taken 807 times.
807 emit countChanged();
67 807 }
68