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: -% 0 / 0 / 0

presentation/ServerDraftCleanup.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QHash>
4 #include <QObject>
5 #include <QString>
6 #include <QTimer>
7
8 #include <functional>
9
10 class ImapService;
11
12 // Removes superseded server draft revisions (Sprint 102 review S102.5.1).
13 // Only the exact UID in the Drafts mailbox whose UIDVALIDITY the server
14 // reported in APPENDUID is touched, through UID EXPUNGE (RFC 4315). A
15 // revision whose identity is unknown or changed is left alone; without
16 // UIDPLUS it keeps \Deleted, because a plain EXPUNGE would also remove
17 // messages other clients only marked as deleted.
18 // F-04 (SPRINT-104): the cleanup runs from every authenticated state —
19 // with a folder open the connection is Selected or Idling, which the
20 // former Authenticated-only guard made unreachable in normal use, so
21 // every saved revision stayed in the Drafts folder. Requests arriving
22 // while a cleanup runs are queued, and a failing SELECT of the Drafts
23 // folder ends the cleanup instead of sticking it active forever.
24 // S106-345/346/347: every step listens to its own command only — the
25 // Drafts SELECT through folderSelectFailed(drafts), the STORE through its
26 // mutation token (a STORE refused with NO ends the cleanup; another
27 // STORE completing meanwhile is not taken for it) — and a watchdog ends a
28 // cleanup whose step never answers.
29 class ServerDraftCleanup : public QObject {
30 Q_OBJECT
31
32 public:
33 // `imap` and `currentFolder` are read at each step (the session owns them).
34 ServerDraftCleanup(std::function<ImapService *()> imap, std::function<QString()> currentFolder,
35 QObject *parent = nullptr);
36 // Called for every completed APPEND; remembers the mailbox identity.
37 void remember(const QString &folder, qint64 uid, quint32 uidValidity);
38 // Marks `uid` in `drafts` \Deleted and expunges exactly it.
39 void remove(const QString &drafts, qint64 uid);
40 61 bool active() const { return m_active; }
41 // The connection ended: forget the running cleanup.
42 void reset();
43 void setWatchdogMs(int ms) { m_watchdog.setInterval(ms); } // tests
44 static constexpr int WatchdogMs = 60000;
45
46 private:
47 struct Pending {
48 QString drafts;
49 qint64 uid = 0;
50 quint32 uidValidity = 0;
51 };
52 void startNext();
53 void storeAndExpunge(const QString &drafts, qint64 uid, quint32 uidValidity);
54 void finish();
55 void disconnectSteps();
56 std::function<ImapService *()> m_imap;
57 std::function<QString()> m_currentFolder;
58 QHash<QString, quint32> m_uidValidity; // folder + '\n' + uid -> UIDVALIDITY
59 QString m_restore; // folder selected before the cleanup
60 bool m_reselect = false;
61 QList<Pending> m_pending; // F-04: queued while a cleanup runs
62 QList<QMetaObject::Connection> m_steps; // pending one-shot step connections
63 bool m_active = false;
64 QTimer m_watchdog; // ends a cleanup whose step never answers
65 qint64 m_storeTokens = 0;
66 };
67