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: 99.2% 119 / 0 / 120
Functions: 100.0% 14 / 0 / 14
Branches: 78.2% 226 / 0 / 289

service/DavXmlHelper.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QDomDocument>
4 #include <QDomElement>
5 #include <QDomNodeList>
6 #include <QString>
7 #include <QXmlStreamReader>
8 #include <optional>
9
10 // ═══════════════════════════════════════════════════════
11 // Shared DAV XML helpers (Sprint 32 – T-331)
12 // Extracted from CardDavClient.cpp for reuse in CalDavClient.
13 // ═══════════════════════════════════════════════════════
14
15 namespace DavXmlHelper {
16
17 struct Limits {
18 qint64 maxBytes = 10 * 1024 * 1024;
19 int maxDepth = 64;
20 qint64 maxElements = 500000;
21 int maxAttributes = 64;
22 };
23
24 // Streaming admission precedes DOM construction and its recursive destruction.
25 1158 inline std::optional<QDomDocument> parse(const QByteArray &bytes, const Limits &limits = {}) {
26
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1157 times.
1158 if (bytes.size() > limits.maxBytes)
27 1 return std::nullopt;
28
1/1
✓ Branch 5 → 6 taken 1157 times.
1157 QXmlStreamReader reader(bytes);
29 1157 int depth = 0;
30 1157 qint64 elements = 0;
31 // Each iteration consumes one token from the bounded input byte array.
32
3/3
✓ Branch 25 → 26 taken 798048 times.
✓ Branch 26 → 7 taken 796900 times.
✓ Branch 26 → 27 taken 1148 times.
798048 while (!reader.atEnd()) {
33
1/1
✓ Branch 7 → 8 taken 796900 times.
796900 const auto token = reader.readNext();
34
3/4
✓ Branch 8 → 9 taken 796899 times.
✓ Branch 8 → 10 taken 1 time.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 796899 times.
796900 if (token == QXmlStreamReader::DTD || token == QXmlStreamReader::EntityReference)
35 1 return std::nullopt;
36
2/2
✓ Branch 11 → 12 taken 305190 times.
✓ Branch 11 → 23 taken 491709 times.
796899 if (token == QXmlStreamReader::StartElement) {
37
4/4
✓ Branch 12 → 13 taken 305184 times.
✓ Branch 12 → 17 taken 6 times.
✓ Branch 13 → 14 taken 305183 times.
✓ Branch 13 → 17 taken 1 time.
610373 if (++depth > limits.maxDepth || ++elements > limits.maxElements ||
38
7/9
✓ Branch 14 → 15 taken 305183 times.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 305182 times.
✓ Branch 19 → 20 taken 305183 times.
✓ Branch 19 → 21 taken 7 times.
✓ Branch 21 → 22 taken 8 times.
✓ Branch 21 → 25 taken 305182 times.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
610373 reader.attributes().size() > limits.maxAttributes)
39 8 return std::nullopt;
40
2/2
✓ Branch 23 → 24 taken 304795 times.
✓ Branch 23 → 25 taken 186914 times.
491709 } else if (token == QXmlStreamReader::EndElement) {
41 304795 --depth;
42 }
43 }
44
3/3
✓ Branch 27 → 28 taken 1148 times.
✓ Branch 28 → 29 taken 23 times.
✓ Branch 28 → 30 taken 1125 times.
1148 if (reader.hasError())
45 23 return std::nullopt;
46
1/1
✓ Branch 30 → 31 taken 1125 times.
1125 QDomDocument document;
47
2/3
✓ Branch 32 → 33 taken 1125 times.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 1125 times.
1125 if (!document.setContent(bytes))
48 ✗ return std::nullopt;
49
1/1
✓ Branch 37 → 38 taken 1125 times.
1125 return document;
50 1157 }
51
52 1141 inline bool parseInto(QDomDocument &document, const QByteArray &bytes, const Limits &limits = {}) {
53
1/1
✓ Branch 2 → 3 taken 1141 times.
1141 auto parsed = parse(bytes, limits);
54
2/2
✓ Branch 4 → 5 taken 20 times.
✓ Branch 4 → 6 taken 1121 times.
1141 if (!parsed) return false;
55
1/1
✓ Branch 7 → 8 taken 1121 times.
1121 document = *parsed;
56 1121 return true;
57 1141 }
58
59 /// Elements found by local name, in document order. Offers the read API of
60 /// QDomNodeList (size/count/length/isEmpty/at/item), which Qt cannot build.
61 class ElementList {
62 public:
63 28316 void append(const QDomElement &element) { m_items.append(element); }
64 30007 int size() const { return int(m_items.size()); }
65 29717 int count() const { return size(); }
66 int length() const { return size(); }
67 5298 bool isEmpty() const { return m_items.isEmpty(); }
68
2/2
✓ Branch 2 → 3 taken 28304 times.
✓ Branch 3 → 4 taken 28304 times.
28304 QDomNode at(int index) const { return m_items.value(index); }
69 QDomNode item(int index) const { return at(index); }
70
71 private:
72 QList<QDomElement> m_items;
73 };
74
75 /// Every descendant element of `parent` whose local name is `localName`,
76 /// whatever its namespace prefix. The documents are parsed WITHOUT namespace
77 /// processing, so the local name is the tag after the first ':'.
78 /// S106-047: the former version tried the bare name and a fixed list of
79 /// common prefixes and returned an empty list for any other legal prefix
80 /// (x1:, ns0:, …) — callers took "empty" for success, and through the F-59
81 /// prune that meant silent local data loss.
82 11887 inline ElementList findElementsByLocalName(const QDomNode &parent, const QString &localName) {
83 11887 ElementList result;
84 // Iterative pre-order traversal (stack-safe for deep documents).
85
1/1
✓ Branch 2 → 3 taken 11887 times.
11887 QDomNode node = parent.firstChild();
86
3/3
✓ Branch 64 → 65 taken 289173 times.
✓ Branch 65 → 4 taken 277286 times.
✓ Branch 65 → 66 taken 11887 times.
289173 while (!node.isNull()) {
87
1/1
✓ Branch 4 → 5 taken 277286 times.
277286 const QDomElement element = node.toElement();
88
3/3
✓ Branch 5 → 6 taken 277286 times.
✓ Branch 6 → 7 taken 179838 times.
✓ Branch 6 → 18 taken 97448 times.
277286 if (!element.isNull()) {
89
1/1
✓ Branch 7 → 8 taken 179838 times.
179838 const QString tag = element.tagName();
90
3/3
✓ Branch 11 → 12 taken 179838 times.
✓ Branch 14 → 15 taken 28316 times.
✓ Branch 14 → 16 taken 151522 times.
179838 if (tag.mid(tag.indexOf(QLatin1Char(':')) + 1) == localName)
91
1/1
✓ Branch 15 → 16 taken 28316 times.
28316 result.append(element);
92 179838 }
93
4/4
✓ Branch 18 → 19 taken 277286 times.
✓ Branch 19 → 20 taken 277286 times.
✓ Branch 21 → 22 taken 175579 times.
✓ Branch 21 → 26 taken 101707 times.
277286 if (!node.firstChild().isNull()) {
94
2/2
✓ Branch 22 → 23 taken 175579 times.
✓ Branch 23 → 24 taken 175579 times.
175579 node = node.firstChild();
95 175579 continue;
96 }
97
15/21
✓ Branch 31 → 32 taken 277286 times.
✓ Branch 32 → 33 taken 277286 times.
✗ Branch 32 → 40 not taken.
✓ Branch 33 → 34 taken 277286 times.
✓ Branch 34 → 35 taken 277286 times.
✓ Branch 35 → 36 taken 187276 times.
✓ Branch 35 → 40 taken 90010 times.
✓ Branch 36 → 37 taken 187276 times.
✓ Branch 37 → 38 taken 187276 times.
✓ Branch 38 → 39 taken 175579 times.
✓ Branch 38 → 40 taken 11697 times.
✓ Branch 41 → 42 taken 187276 times.
✓ Branch 41 → 43 taken 90010 times.
✓ Branch 43 → 44 taken 277286 times.
✗ Branch 43 → 45 not taken.
✓ Branch 45 → 27 taken 175579 times.
✓ Branch 45 → 46 taken 101707 times.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 86 not taken.
✗ Branch 88 → 89 not taken.
✗ Branch 88 → 90 not taken.
277286 while (!node.isNull() && node.nextSibling().isNull() && node.parentNode() != parent)
98
2/2
✓ Branch 27 → 28 taken 175579 times.
✓ Branch 28 → 29 taken 175579 times.
175579 node = node.parentNode();
99
5/8
✓ Branch 46 → 47 taken 101707 times.
✓ Branch 47 → 48 taken 101707 times.
✗ Branch 47 → 50 not taken.
✓ Branch 48 → 49 taken 101707 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 101707 times.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 101707 times.
101707 if (node.isNull() || node == parent) break;
100
2/2
✓ Branch 54 → 55 taken 101707 times.
✓ Branch 55 → 56 taken 101707 times.
101707 node = node.nextSibling();
101 277286 }
102 11887 return result;
103 11887 }
104
105 /// Find the first element by local name using namespace-agnostic traversal.
106 /// This handles any arbitrary namespace prefix (x1:, ns0:, etc.).
107 /// Note: the documents here are parsed WITHOUT namespace processing, so
108 /// QDomElement::localName() is always empty — the local name must be
109 /// derived from tagName() by stripping the prefix. QDom also does not
110 /// support the DOM "*" wildcard, so the fallback walks children manually.
111 28403 inline QDomElement findFirstElementByLocalName(const QDomElement &parent,
112 const QString &localName) {
113 // Iterative pre-order traversal visits every descendant at most once.
114 // It also remains stack-safe if a caller provides an independently built DOM.
115
1/1
✓ Branch 2 → 3 taken 28403 times.
28403 QDomNode node = parent.firstChild();
116
3/3
✓ Branch 65 → 66 taken 422820 times.
✓ Branch 66 → 4 taken 421801 times.
✓ Branch 66 → 67 taken 1019 times.
422820 while (!node.isNull()) {
117
1/3
✓ Branch 4 → 5 taken 421801 times.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 100 not taken.
421801 const QDomElement element = node.toElement();
118
3/3
✓ Branch 5 → 6 taken 421801 times.
✓ Branch 6 → 7 taken 275543 times.
✓ Branch 6 → 22 taken 146258 times.
421801 if (!element.isNull()) {
119
1/1
✓ Branch 7 → 8 taken 275543 times.
275543 const QString tag = element.tagName();
120
3/3
✓ Branch 11 → 12 taken 275543 times.
✓ Branch 14 → 15 taken 27384 times.
✓ Branch 14 → 16 taken 248159 times.
275543 if (tag.mid(tag.indexOf(QLatin1Char(':')) + 1) == localName)
121 27384 return element;
122 275543 }
123
4/4
✓ Branch 22 → 23 taken 394417 times.
✓ Branch 23 → 24 taken 394417 times.
✓ Branch 25 → 26 taken 244008 times.
✓ Branch 25 → 30 taken 150409 times.
394417 if (!node.firstChild().isNull()) {
124
2/2
✓ Branch 26 → 27 taken 244008 times.
✓ Branch 27 → 28 taken 244008 times.
244008 node = node.firstChild();
125 244008 continue;
126 }
127
15/21
✓ Branch 35 → 36 taken 361332 times.
✓ Branch 36 → 37 taken 361332 times.
✗ Branch 36 → 44 not taken.
✓ Branch 37 → 38 taken 361332 times.
✓ Branch 38 → 39 taken 361332 times.
✓ Branch 39 → 40 taken 211936 times.
✓ Branch 39 → 44 taken 149396 times.
✓ Branch 40 → 41 taken 211936 times.
✓ Branch 41 → 42 taken 211936 times.
✓ Branch 42 → 43 taken 210923 times.
✓ Branch 42 → 44 taken 1013 times.
✓ Branch 45 → 46 taken 211936 times.
✓ Branch 45 → 47 taken 149396 times.
✓ Branch 47 → 48 taken 361332 times.
✗ Branch 47 → 49 not taken.
✓ Branch 49 → 31 taken 210923 times.
✓ Branch 49 → 50 taken 150409 times.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 89 not taken.
✗ Branch 91 → 92 not taken.
✗ Branch 91 → 93 not taken.
361332 while (!node.isNull() && node.nextSibling().isNull() && node.parentNode() != parent)
128
2/2
✓ Branch 31 → 32 taken 210923 times.
✓ Branch 32 → 33 taken 210923 times.
210923 node = node.parentNode();
129
5/8
✓ Branch 50 → 51 taken 150409 times.
✓ Branch 51 → 52 taken 150409 times.
✗ Branch 51 → 54 not taken.
✓ Branch 52 → 53 taken 150409 times.
✗ Branch 53 → 54 not taken.
✓ Branch 53 → 55 taken 150409 times.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 58 taken 150409 times.
150409 if (node.isNull() || node == parent) break;
130
2/2
✓ Branch 58 → 59 taken 150409 times.
✓ Branch 59 → 60 taken 150409 times.
150409 node = node.nextSibling();
131 394417 }
132
1/1
✓ Branch 67 → 68 taken 1019 times.
1019 return {};
133 28403 }
134
135 /// Same but for the whole document.
136 880 inline ElementList findElementsByLocalNameDoc(const QDomDocument &doc, const QString &localName) {
137 880 return findElementsByLocalName(doc, localName);
138 }
139
140 /// Local name of an element of a document parsed without namespace processing.
141 21659 inline QString localNameOf(const QDomElement &element) {
142
1/1
✓ Branch 2 → 3 taken 21659 times.
21659 const QString tag = element.tagName();
143
3/5
✓ Branch 3 → 4 taken 21659 times.
✓ Branch 5 → 6 taken 21659 times.
✗ Branch 5 → 10 not taken.
✓ Branch 9 → 11 taken 21659 times.
✗ Branch 10 → 11 not taken.
43318 return element.localName().isEmpty() ? tag.mid(tag.indexOf(QLatin1Char(':')) + 1) : element.localName();
144 21659 }
145
146 /// The DAV:href inside the first `property` element (current-user-principal,
147 /// calendar-home-set, addressbook-home-set …); empty when missing.
148 12 inline QString hrefOfProperty(const QDomElement &root, const QString &property) {
149
1/1
✓ Branch 2 → 3 taken 12 times.
12 const QDomElement element = findFirstElementByLocalName(root, property);
150
3/3
✓ Branch 3 → 4 taken 12 times.
✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 6 taken 9 times.
12 if (element.isNull())
151 3 return {};
152
3/3
✓ Branch 9 → 10 taken 9 times.
✓ Branch 10 → 11 taken 9 times.
✓ Branch 11 → 12 taken 9 times.
9 return findFirstElementByLocalName(element, QStringLiteral("href")).text().trimmed();
153 12 }
154
155 /// RFC 3744: a collection without write, write-content or all privilege is
156 /// read-only; servers that do not report privileges stay writable
157 /// (Sprint 93 S93.5.8, shared with CardDAV in Sprint 97).
158 312 inline bool readOnlyFromPrivileges(const QDomElement &response) {
159
1/1
✓ Branch 5 → 6 taken 312 times.
312 const QDomElement privileges = findFirstElementByLocalName(response, QStringLiteral("current-user-privilege-set"));
160
14/21
✓ Branch 8 → 9 taken 312 times.
✓ Branch 9 → 10 taken 49 times.
✓ Branch 9 → 16 taken 263 times.
✓ Branch 13 → 14 taken 49 times.
✓ Branch 14 → 15 taken 49 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 49 times.
✓ Branch 18 → 19 taken 49 times.
✓ Branch 18 → 20 taken 263 times.
✓ Branch 20 → 21 taken 49 times.
✓ Branch 20 → 22 taken 263 times.
✓ Branch 22 → 23 taken 49 times.
✓ Branch 22 → 24 taken 263 times.
✓ Branch 24 → 25 taken 263 times.
✓ Branch 24 → 26 taken 49 times.
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 76 not taken.
✗ Branch 78 → 79 not taken.
✗ Branch 78 → 80 not taken.
✗ Branch 82 → 83 not taken.
✗ Branch 82 → 84 not taken.
361 if (privileges.isNull() || findFirstElementByLocalName(privileges, QStringLiteral("privilege")).isNull())
161 263 return false;
162
3/11
✓ Branch 29 → 30 taken 49 times.
✓ Branch 60 → 61 taken 49 times.
✗ Branch 60 → 62 not taken.
✓ Branch 62 → 63 taken 49 times.
✗ Branch 62 → 64 not taken.
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 112 not taken.
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 116 not taken.
✗ Branch 118 → 119 not taken.
✗ Branch 118 → 120 not taken.
98 return findFirstElementByLocalName(privileges, QStringLiteral("write")).isNull() &&
163
11/19
✓ Branch 30 → 31 taken 49 times.
✓ Branch 31 → 32 taken 5 times.
✓ Branch 31 → 45 taken 44 times.
✓ Branch 35 → 36 taken 5 times.
✓ Branch 36 → 37 taken 5 times.
✓ Branch 37 → 38 taken 5 times.
✗ Branch 37 → 45 not taken.
✓ Branch 54 → 55 taken 5 times.
✓ Branch 54 → 56 taken 44 times.
✓ Branch 56 → 57 taken 5 times.
✓ Branch 56 → 58 taken 44 times.
✓ Branch 58 → 59 taken 49 times.
✗ Branch 58 → 60 not taken.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 100 not taken.
✗ Branch 102 → 103 not taken.
✗ Branch 102 → 104 not taken.
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 108 not taken.
157 findFirstElementByLocalName(privileges, QStringLiteral("write-content")).isNull() &&
164
12/18
✓ Branch 41 → 42 taken 5 times.
✓ Branch 42 → 43 taken 5 times.
✓ Branch 43 → 44 taken 4 times.
✓ Branch 43 → 45 taken 1 time.
✓ Branch 46 → 47 taken 5 times.
✓ Branch 46 → 48 taken 44 times.
✓ Branch 48 → 49 taken 5 times.
✓ Branch 48 → 50 taken 44 times.
✓ Branch 50 → 51 taken 5 times.
✓ Branch 50 → 52 taken 44 times.
✓ Branch 52 → 53 taken 5 times.
✓ Branch 52 → 54 taken 44 times.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 88 not taken.
✗ Branch 90 → 91 not taken.
✗ Branch 90 → 92 not taken.
✗ Branch 94 → 95 not taken.
✗ Branch 94 → 96 not taken.
54 findFirstElementByLocalName(privileges, QStringLiteral("all")).isNull();
165 312 }
166
167 /// RFC 6578 sync-collection answer: the collection-level sync-token and the
168 /// hrefs answered with a response-level 404 (removed since the token).
169 /// Changed members are read by the caller (they carry a propstat).
170 52 inline bool parseSyncCollectionStatus(const QByteArray &xml, QStringList *removed, QString *token) {
171
1/1
✓ Branch 2 → 3 taken 52 times.
52 QDomDocument doc;
172
3/3
✓ Branch 3 → 4 taken 52 times.
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 51 times.
52 if (!parseInto(doc, xml))
173 1 return false;
174
1/1
✓ Branch 6 → 7 taken 51 times.
51 const QDomElement root = doc.documentElement();
175
6/6
✓ Branch 7 → 8 taken 51 times.
✓ Branch 32 → 33 taken 5369 times.
✓ Branch 33 → 34 taken 5369 times.
✓ Branch 36 → 37 taken 5420 times.
✓ Branch 37 → 9 taken 5369 times.
✓ Branch 37 → 38 taken 51 times.
5420 for (QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling()) {
176
1/1
✓ Branch 9 → 10 taken 5369 times.
5369 const QDomElement element = node.toElement();
177
10/17
✓ Branch 11 → 12 taken 5369 times.
✓ Branch 13 → 14 taken 5369 times.
✗ Branch 13 → 18 not taken.
✓ Branch 14 → 15 taken 5369 times.
✓ Branch 16 → 17 taken 5369 times.
✓ Branch 17 → 18 taken 50 times.
✓ Branch 17 → 19 taken 5319 times.
✓ Branch 20 → 21 taken 5369 times.
✗ Branch 20 → 22 not taken.
✓ Branch 22 → 23 taken 5369 times.
✗ Branch 22 → 24 not taken.
✓ Branch 24 → 25 taken 50 times.
✓ Branch 24 → 31 taken 5319 times.
✗ Branch 112 → 113 not taken.
✗ Branch 112 → 114 not taken.
✗ Branch 116 → 117 not taken.
✗ Branch 116 → 118 not taken.
5369 if (element.localName() == QLatin1String("sync-token") || element.tagName().endsWith(QLatin1String("sync-token")))
178
2/2
✓ Branch 25 → 26 taken 50 times.
✓ Branch 26 → 27 taken 50 times.
50 *token = element.text().trimmed();
179 5420 }
180
1/1
✓ Branch 42 → 43 taken 51 times.
51 const auto responses = findElementsByLocalNameDoc(doc, QStringLiteral("response"));
181
2/2
✓ Branch 104 → 46 taken 5319 times.
✓ Branch 104 → 105 taken 51 times.
5370 for (int i = 0; i < responses.count(); ++i) {
182
2/2
✓ Branch 46 → 47 taken 5319 times.
✓ Branch 47 → 48 taken 5319 times.
5319 const QDomElement response = responses.at(i).toElement();
183 // A removed member has a response-level status and no propstat.
184 5319 QString status;
185
6/6
✓ Branch 49 → 50 taken 5319 times.
✓ Branch 62 → 63 taken 10638 times.
✓ Branch 63 → 64 taken 10638 times.
✓ Branch 66 → 67 taken 15957 times.
✓ Branch 67 → 51 taken 10638 times.
✓ Branch 67 → 68 taken 5319 times.
15957 for (QDomNode child = response.firstChild(); !child.isNull(); child = child.nextSibling()) {
186
1/1
✓ Branch 51 → 52 taken 10638 times.
10638 const QDomElement element = child.toElement();
187
3/3
✓ Branch 53 → 54 taken 10638 times.
✓ Branch 56 → 57 taken 10 times.
✓ Branch 56 → 61 taken 10628 times.
10638 if (localNameOf(element) == QLatin1String("status"))
188
1/1
✓ Branch 57 → 58 taken 10 times.
10 status = element.text();
189 15957 }
190
3/3
✓ Branch 70 → 71 taken 5319 times.
✓ Branch 71 → 72 taken 5313 times.
✓ Branch 71 → 73 taken 6 times.
5319 if (!status.contains(QLatin1String(" 404")))
191 5313 continue;
192
1/1
✓ Branch 76 → 77 taken 6 times.
6 const auto hrefs = findElementsByLocalName(response, QStringLiteral("href"));
193
1/2
✓ Branch 80 → 81 taken 6 times.
✗ Branch 80 → 91 not taken.
6 if (!hrefs.isEmpty())
194
5/5
✓ Branch 81 → 82 taken 6 times.
✓ Branch 82 → 83 taken 6 times.
✓ Branch 83 → 84 taken 6 times.
✓ Branch 84 → 85 taken 6 times.
✓ Branch 85 → 86 taken 6 times.
6 removed->append(hrefs.at(0).toElement().text().trimmed());
195 10632 }
196 51 return true;
197 52 }
198
199 } // namespace DavXmlHelper
200