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% 1 / 0 / 1
Functions: 100.0% 1 / 0 / 1
Branches: 75.0% 3 / 0 / 4

service/DavPushXml.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QByteArray>
4 #include <QHash>
5 #include <QString>
6 #include <optional>
7
8 #include "data/DavPushModels.h"
9
10 // Sprint 96 S96.1.2 / S96.2.3: namespace-exact DAV-Push XML (WebDAV-Push
11 // namespace https://bitfire.at/webdav-push). Unlike the QDom helpers of the
12 // CalDAV client this parser honours namespaces: a foreign element with the
13 // same local name never supplies a topic, key or message.
14 //
15 // Profiles (ADR-96-2): the installed Nextcloud dav_push 1.0.2 returns no
16 // supported-triggers and no type attribute on the VAPID key; the draft
17 // requires both. Both are accepted, security-relevant values (key bytes,
18 // topic, structure) are validated strictly.
19 namespace DavPushXml {
20
21 inline const QString kNamespace = QStringLiteral("https://bitfire.at/webdav-push");
22
23 // Bounds for documents from the network.
24 constexpr int kMaxDepth = 16;
25 constexpr int kMaxMessageBytes = 16 * 1024;
26
27 // The push properties a discovery PROPFIND asks for (prefix "P").
28 QByteArray discoveryProperties();
29
30 // Per collection href (as written in the response) the classified offer,
31 // read from successful (2xx) propstat blocks only. Collections whose push
32 // properties were all answered 404 are Unsupported. nullopt for broken XML.
33 std::optional<QHash<QString, DavPushOffer>> parseDiscovery(const QByteArray &multistatus,
34 QString *error = nullptr);
35
36 // The push-register body for a Web Push subscription, accepted by the
37 // 1.0.2 profile and the draft (content-encoding and the content-update
38 // trigger are ignored by 1.0.2).
39 QByteArray registerBody(const QString &pushResource, const QByteArray &publicKey, const QByteArray &authSecret);
40
41 struct PushMessage {
42 QString topic; // empty for a VAPID key rotation notice
43 bool contentUpdate = false;
44 QString syncToken; // opaque; "" when the message carries none
45 bool propertyUpdate = false;
46 bool transportsChanged = false; // property-update naming P:transports
47
3/4
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 6 taken 6 times.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 6 not taken.
8 bool isKeyRotation() const { return topic.isEmpty() && transportsChanged; }
48 };
49
50 // Parses a decrypted push message. Rejects DTDs, more than kMaxDepth
51 // levels, more than kMaxMessageBytes and any root other than P:push-message.
52 std::optional<PushMessage> parsePushMessage(const QByteArray &xml, QString *error = nullptr);
53
54 // HTTP Expires of a registration: IMF-fixdate ("… GMT", RFC 9110) and the
55 // dav_push 1.0.2 form "Sat, 10 Oct 2026 19:12:38 +0000+" (numeric offset
56 // and a trailing "+"). Epoch seconds, nullopt when unusable.
57 std::optional<qint64> parseHttpDate(const QString &value);
58
59 } // namespace DavPushXml
60