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

app/core/ContactBookSync.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QHash>
4 #include <QObject>
5 #include <QSet>
6 #include <QStringList>
7
8 #include "data/ContactModels.h"
9
10 class CardDavClient;
11 class ContactStore;
12 struct DavCardChanges;
13 struct DavCardResource;
14
15 // One incremental sync of one address book (Sprint 97 S97.1.5,
16 // CONTACT-SYNC-INCR; gate G5):
17 //
18 // 1. PROPFIND Depth 0 of the book (name, privileges, CTag, sync-token,
19 // supported versions). An unchanged sync-token or CTag ends the run:
20 // one request, no card downloaded.
21 // 2. sync-collection (RFC 6578) with the stored token for ETags only; an
22 // expired token falls back to a full listing, a server without the
23 // report to PROPFIND Depth 1 of the ETags and a comparison with the
24 // stored ones.
25 // 3. addressbook-multiget of the changed hrefs in batches of at most 100;
26 // an answer above DavNetworkLimits splits the batch, a single card that
27 // is too large or unreadable is skipped with a per-card error instead of
28 // failing the book.
29 // 4. Cards with a queued local change are left to the outbox (it merges on
30 // 412). Deletions come from the sync result (or the full listing) and
31 // only touch this book. The token is stored after the cards are applied.
32 // 5. Photos given as a URI on the book's origin are fetched once
33 // (ContactPhotoFetch, S97.5.7); nothing to fetch means no request.
34 //
35 // The first complete fetch removes the book's D-5 legacy cards.
36 class ContactBookSync : public QObject {
37 Q_OBJECT
38 public:
39 static constexpr int MaxBatch = 100;
40
41 ContactBookSync(ContactStore *store, CardDavClient *client, qint64 bookId, QObject *parent = nullptr);
42 void start();
43
44 82 int requests() const { return m_requests; }
45 82 int cardsDownloaded() const { return m_downloaded; }
46 int skippedCards() const { return m_skipped; }
47 // Sprint 96: the book's push offer from step 1 (Unknown before it ran).
48 82 DavPushOffer pushOffer() const { return m_server.push; }
49
50 signals:
51 // ok = the book is complete and consistent; changedKeys = card keys that
52 // were added, changed or removed; bulk = too many for per-card updates.
53 void finished(bool ok, const QStringList &changedKeys, bool bulk);
54 void progressed(); // any answer arrived (the caller's inactivity timeout)
55
56 private:
57 void onBook(const AddressBookInfo &server);
58 void onChanges(const DavCardChanges &changes);
59 void onEtags(const QHash<QString, QString> &etags);
60 void fetchNextBatch();
61 void onCards(const QList<DavCardResource> &cards, const QStringList &missing);
62 void onBatchFailed(const QStringList &hrefs, const QString &error, bool tooLarge);
63 void applyRemovals();
64 void complete();
65 void fail(const QString &error);
66
67 ContactStore *m_store;
68 CardDavClient *m_client;
69 qint64 m_bookId;
70 AddressBookInfo m_book; // stored state at start
71 AddressBookInfo m_server; // properties read in step 1
72 QString m_newToken;
73 bool m_fullListing = false;
74 QStringList m_toFetch;
75 QList<QStringList> m_batches;
76 QStringList m_removed;
77 QString m_moreToken; // F-35: continue a truncated listing from it
78 // S106-957: a full listing the server truncated is collected over its
79 // continuation pages; the absence comparison runs once the last page came.
80 bool m_collectingFullListing = false;
81 // S106-062: the token the current continuation page was requested with,
82 // and the truncated pages of this run (bounded).
83 QString m_pageRequestToken;
84 int m_truncatedPages = 0;
85 static constexpr int MaxTruncatedPages = 1000;
86 QSet<QString> m_fullListingHrefs;
87 QStringList m_changedKeys;
88 int m_requests = 0;
89 int m_downloaded = 0;
90 int m_skipped = 0;
91 bool m_done = false;
92 };
93