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

service/DavPushClient.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QByteArray>
4 #include <QObject>
5 #include <QString>
6 #include <functional>
7
8 class QNetworkAccessManager;
9 class QNetworkReply;
10
11 // Sprint 96 S96.2.3: WebDAV-Push subscription requests of one DAV account —
12 // POST push-register (registration and renewal) and DELETE of the own
13 // registration URL. Uses the DAV credentials only towards the DAV origin;
14 // a Location on another origin is a protocol failure, never followed.
15 //
16 // Profiles (ADR-96-2): draft 201/204, dav_push 1.0.2 201 with an XML body;
17 // Expires as IMF-fixdate or "… +0000+". A missing or unusable Expires is a
18 // failure: an unlimited subscription is never assumed.
19 class DavPushClient final : public QObject {
20 Q_OBJECT
21 public:
22 enum class Outcome {
23 Ok,
24 NotFound, // register: collection gone; unregister: already removed (counts as done)
25 Unauthorized, // 401: DAV credentials rejected
26 Forbidden, // 403: privileges or no-trigger-supported precondition
27 Incompatible, // 400/415, missing/foreign Location, missing Expires
28 RateLimited, // 429/503 (retryAfterSeconds when given)
29 ServerError, // other 5xx
30 Transport, // network/TLS/timeout/limit
31 };
32 198 Q_ENUM(Outcome)
33
34 struct Result {
35 quint64 request = 0;
36 Outcome outcome = Outcome::Transport;
37 int status = 0;
38 QString collectionPath; // register only
39 QString location; // exact registration URL from the server
40 qint64 expiresAt = 0; // local epoch seconds (server Date skew applied)
41 int retryAfterSeconds = 0;
42 QString detail; // technical, redacted (no URLs, no secrets)
43 };
44
45 DavPushClient(const QString &serverUrl, const QString &username, const QString &password,
46 QObject *parent = nullptr);
47
48 quint64 registerSubscription(const QString &collectionPath, const QString &pushResource,
49 const QByteArray &publicKey, const QByteArray &authSecret);
50 quint64 unregisterSubscription(const QString &registrationUrl);
51
52 // Test seams.
53 void setNetworkAccessManager(QNetworkAccessManager *nam);
54 7 void setClock(std::function<qint64()> clock) { m_clock = std::move(clock); }
55
56 signals:
57 void registered(const DavPushClient::Result &result);
58 void unregistered(const DavPushClient::Result &result);
59
60 private:
61 QByteArray authHeader() const;
62 Result classify(QNetworkReply *reply, quint64 request) const;
63 void finishRegister(QNetworkReply *reply, quint64 request, const QString &collectionPath);
64 qint64 now() const;
65
66 QNetworkAccessManager *m_nam = nullptr;
67 QString m_serverUrl;
68 QString m_username;
69 QString m_password;
70 quint64 m_nextRequest = 0;
71 std::function<qint64()> m_clock;
72 };
73
74
4/7
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 14 not taken.
✓ Branch 9 → 10 taken 2 times.
✓ Branch 10 → 11 taken 2 times.
✗ Branch 14 → 15 not taken.
2 Q_DECLARE_METATYPE(DavPushClient::Result)
75