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

service/SettingsSyncService.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QObject>
4 #include <QString>
5 #include <QTimer>
6 #include <functional>
7
8 #include "data/AccountConfig.h"
9 #include "data/Models.h"
10 #include "data/SettingsSyncModels.h"
11 #include "service/ImapService.h"
12
13 class ConnectionHealthMonitor;
14
15 // T-312/T-314: Manages settings synchronisation via a dedicated IMAP connection.
16 // Stores settings as a virtual mail (JSON body) in a configurable IMAP folder.
17 // Uses IMAP IDLE for real-time change detection from other clients.
18 //
19 // Architecture: owns its own ImapService instance (separate from the main
20 // connection) to avoid interference with regular mail operations.
21 //
22 // T-720: auto-reconnect (and dead-socket detection) for the dedicated IMAP
23 // connection is delegated to ConnectionHealthMonitor (Sprint 72). The
24 // m_reconnectTimer/m_reconnectAttempts members and handleDisconnect()/
25 // onReconnectTimer() methods have been removed.
26 class SettingsSyncService : public QObject {
27 3 Q_OBJECT
28 #ifdef MAILJD_UNIT_TEST
29 friend class TestSettingsSyncService;
30 friend class TestSprint79Services;
31 #endif
32
33 public:
34 explicit SettingsSyncService(QObject *parent = nullptr);
35 ~SettingsSyncService() override;
36
37 // Configure and connect
38 void configure(const ImapConfig &config, const QString &syncFolder);
39 void setEnabled(bool enabled);
40 4 bool isEnabled() const { return m_enabled; }
41 2 QString syncFolder() const { return m_syncFolder; }
42 bool readyForOperation() const;
43
44 #ifdef MAILJD_E2E_TESTING
45 // Read-only transport seam for platform lifecycle assertions. Production
46 // callers cannot reach the owned IMAP connection.
47 ImapService *transportForE2e() const { return m_imap; }
48 #endif
49
50 // Upload current settings to IMAP
51 void uploadSettings(const SyncPayload &payload);
52
53 // Fetch latest settings from IMAP
54 void fetchLatestSettings();
55
56 // Start/stop IDLE-watching on the sync folder
57 void startWatching();
58 void stopWatching();
59
60 // Disconnect and clean up
61 void shutdown();
62
63 signals:
64 void settingsReceived(const SyncPayload &payload);
65 void fetchComplete(bool settingsFound);
66 void uploadComplete();
67 void syncError(const QString &error);
68 void syncFolderReady();
69 void connected();
70 void connectionLost();
71
72 private slots:
73 void onStateChanged(ImapService::State newState);
74 void onFolderListReceived(const QList<FolderInfo> &folders);
75 void onFolderSelected(const QString &path, int messageCount,
76 quint32 uidValidity, quint64 highestModseq);
77 void onFolderCreated(const QString &folderPath);
78 void onSearchResultReceived(const QList<qint64> &uids);
79 void onRawBodyReceived(qint64 uid, const QByteArray &rawBody);
80 void fetchNextCandidate();
81 void onMessageAppended(const QString &folder, qint64 uid);
82 void onIdleNewMessages(int newCount);
83 void onAppendError(const QString &error);
84 void onFolderOperationError(const QString &op, const QString &error);
85 void onExpungeComplete();
86 void onExpungeFailed(const QString &error);
87
88 private:
89 enum class Phase {
90 Idle,
91 CheckingFolder, // LIST to check if sync folder exists
92 CreatingFolder, // CREATE sync folder
93 SelectingFolder, // SELECT sync folder
94 Fetching, // SEARCH + FETCH latest settings
95 Uploading, // APPEND new settings
96 CleaningUp, // Recheck UIDVALIDITY, remove one validated previous version
97 WatchingIdle, // IDLE on sync folder
98 };
99
100 void retireTransport(ImapService::DisconnectReason reason);
101 void afterIdle(std::function<void()> command);
102 quint64 m_generation = 0;
103 void checkOrCreateFolder();
104 void doFetch();
105 void doUpload();
106 void cleanupOldSettings(qint64 keepUid);
107 void finishUpload();
108 void startIdleWatch();
109
110 ImapService *m_imap = nullptr;
111 // T-720: Health monitor for the dedicated IMAP connection. Periodic
112 // liveness probes + exponential-backoff reconnect + suspend/network
113 // reactivity — same code path as the main + body + search connections.
114 ConnectionHealthMonitor *m_health = nullptr;
115 ImapConfig m_config;
116 QString m_syncFolder;
117 bool m_enabled = false;
118 Phase m_phase = Phase::Idle;
119
120 // State tracking
121 qint64 m_currentSettingsUid = -1; // UID of the current settings mail
122 QList<qint64> m_candidateUids; // remaining search hits, newest first
123 int m_messageCount = 0; // Messages in sync folder
124 QByteArray m_pendingUpload; // RFC-2822 message to upload
125 qint64 m_newAppendedUid = -1; // UID of just-appended message
126 qint64 m_validatedSettingsUid = -1;
127 quint32 m_validatedUidValidity = 0;
128 qint64 m_previousSettingsUid = -1;
129 quint32 m_uploadUidValidity = 0;
130 };
131