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

presentation/QuickAccountSettings.h
Line Branch Exec Source
1 #pragma once
2
3 #include "AccountConnectionTest.h"
4 #include "AccountOverview.h"
5 #include "AccountServiceCheck.h"
6 #include "AccountSetupSession.h"
7 #include "DavConnectionTest.h"
8 #include "DavCollectionDiscovery.h"
9 #include "DavServerHints.h"
10 #include "app/core/SettingsSyncSession.h"
11 #include <QAbstractItemModel>
12 #include <QHash>
13 #include <QObject>
14 #include <QPointer>
15 #include <QVariantMap>
16 #include <functional>
17
18 class ExternalWhitelistModel;
19 class MailSessionCore;
20 class QuickPimBackend;
21 class QuickPreferences;
22 class WorkspaceState;
23
24 // Account, DAV-account and presentation settings of the Quick frontend
25 // (Sprint 91 S91.2.2, extracted from QuickMailBackend). QML reaches it as
26 // `backend.settings`.
27 //
28 // Owner: QuickMailBackend (value member, declared where the image
29 // whitelist model was so its construction order is unchanged). GUI thread
30 // only; account and DAV saves stage keyring work through their request
31 // objects (m_settingsRequests). The backend calls connectSettingsSync() and
32 // connectDavDiscovery() at the positions of the former wireSettingsSync()
33 // and wireDavDiscovery() blocks, so every receiver order is unchanged.
34 // davSettingsChanged has three receivers wired here, in this order:
35 // settings sync, DAV discovery invalidation, contact interval.
36 class QuickAccountSettings final : public QObject {
37 51 Q_OBJECT
38 Q_PROPERTY(SettingsSyncSession *settingsSync READ settingsSync CONSTANT)
39 Q_PROPERTY(QAbstractItemModel *imageWhitelist READ imageWhitelist CONSTANT)
40 Q_PROPERTY(QString imagePolicyMode READ imagePolicyMode WRITE setImagePolicyMode NOTIFY imagePolicyModeChanged)
41 Q_PROPERTY(QString defaultReadingMode READ defaultReadingMode WRITE setDefaultReadingMode NOTIFY defaultReadingModeChanged)
42 Q_PROPERTY(QAbstractItemModel *davDiscovery READ davDiscovery CONSTANT)
43 // S100.4.8: "New on the server" / "N more on the server" in the sidebars.
44 Q_PROPERTY(DavServerHints *serverHints READ serverHints CONSTANT)
45 // Q07: the account form's connection test (idle/testing/success/failed).
46 Q_PROPERTY(AccountConnectionTest *connectionTest READ connectionTest CONSTANT)
47 // Sprint 93 S93.6.3: "Test connection" of the DAV account form.
48 Q_PROPERTY(DavConnectionTest *davConnectionTest READ davConnectionTest CONSTANT)
49 // Sprint 100 S100.4.2/S100.4.4: "Save = test" of the editors and the guided setup.
50 Q_PROPERTY(AccountServiceCheck *serviceCheck READ serviceCheck CONSTANT)
51 Q_PROPERTY(AccountSetupSession *setup READ setup CONSTANT)
52 // Sprint 100 S100.1.5 (D-4): one entry per account with its services.
53 Q_PROPERTY(QVariantList accountOverview READ accountOverview NOTIFY accountOverviewChanged)
54 public:
55 struct Deps {
56 std::function<QString()> activeAccountId;
57 // A send, mail action or server-draft cleanup of the active account runs.
58 std::function<bool()> sendOrActionPending;
59 std::function<void()> loadLocalFolders;
60 // Sprint 100 S100.1.5: mail connection and rule state of the active account.
61 std::function<AccountOverview::Active()> activeState;
62 };
63 QuickAccountSettings(MailSessionCore &session, WorkspaceState &workspace,
64 QuickPreferences &preferences, QuickPimBackend &pim,
65 const QString &profileDirectory, Deps deps, QObject *parent = nullptr);
66 void connectSettingsSync();
67 void connectDavDiscovery();
68 // Deletes staged account/DAV save requests (their keyring work is owned
69 // by the request objects); called from the backend destructor.
70 void destroyPendingRequests();
71
72 SettingsSyncSession *settingsSync() const;
73 QAbstractItemModel *imageWhitelist() const;
74 QString imagePolicyMode() const;
75 void setImagePolicyMode(const QString &mode);
76 QString defaultReadingMode() const;
77 void setDefaultReadingMode(const QString &mode);
78 24 QAbstractItemModel *davDiscovery() { return &m_davDiscovery; }
79 1531 DavServerHints *serverHints() { return &m_serverHints; }
80 1 AccountConnectionTest *connectionTest() { return &m_connectionTest; }
81 6 DavConnectionTest *davConnectionTest() { return &m_davConnectionTest; }
82 // F4.9: configured accounts from the profile's accounts directory, for the
83 // read-only Accounts settings tab.
84 Q_INVOKABLE QVariantList configuredAccounts() const;
85 // F4.9: validate + persist an account from the Accounts form. Passwords go
86 // to the OS keyring through AccountConfigLoader::save. Returns {ok, error}.
87 // S106-251: no product caller — the editors use saveAccountAsync, which
88 // also reports field errors and re-keys the cache on a rename. Tests keep
89 // this synchronous form; product code must not call it.
90 Q_INVOKABLE QVariantMap saveAccount(const QVariantMap &fields);
91 // Product settings path: returns {ok, pending, requestId, fieldErrors}.
92 // Completion is emitted only for the matching request; cancellation owns
93 // and destroys the staged keyring operation.
94 Q_INVOKABLE QVariantMap saveAccountAsync(const QVariantMap &fields);
95 // Q07: delete a stored account (config file, keyring secrets and the
96 // account's scoped recovery draft). Removing the active account is
97 // refused while a send, mail action, draft cleanup or undo is running,
98 // and switches the session to the first remaining account (or the
99 // unconfigured state) afterwards.
100 Q_INVOKABLE QVariantMap removeAccount(const QString &id);
101 // D3 DAV group: CalDAV scheduler interval in minutes (0 disables); the
102 // CalendarSyncCoordinator reads the same caldav/syncIntervalMin key and is
103 // re-armed live when the value changes.
104 Q_PROPERTY(int caldavSyncIntervalMinutes READ caldavSyncIntervalMinutes
105 WRITE setCaldavSyncIntervalMinutes NOTIFY davSettingsChanged)
106 int caldavSyncIntervalMinutes() const;
107 void setCaldavSyncIntervalMinutes(int minutes);
108 // D3 DAV group: {id, serverUrl, username} rows from carddav/accounts.
109 Q_PROPERTY(QVariantList davAccounts READ davAccounts NOTIFY davSettingsChanged)
110 Q_INVOKABLE QVariantList davAccounts() const;
111 // Validate + persist a DAV account (https origin enforced through
112 // DavCredentials::canonicalOrigin). New accounts get a stable UUID id; an
113 // empty password on update keeps the stored keyring secret. The secret is
114 // removed (and dependent calendar configs cleaned) on removeDavAccount.
115 // Returns {ok, error}.
116 Q_INVOKABLE QVariantMap saveDavAccount(const QVariantMap &fields);
117 Q_INVOKABLE QVariantMap saveDavAccountAsync(const QVariantMap &fields);
118 Q_INVOKABLE void cancelSettingsRequest(const QString &requestId);
119 Q_INVOKABLE bool removeDavAccount(const QString &id);
120 // External-image policy: writes go through the shared ExternalContentPolicy
121 // and the cache whitelist, so a running HTML reader refreshes immediately.
122 Q_INVOKABLE bool addImageWhitelistDomain(const QString &domain);
123 Q_INVOKABLE bool removeImageWhitelistEntry(qint64 entryId);
124 QVariantList accountOverview() const;
125 // Sprint 100 D-4: link a calendar/contact account to a mail account ("" unlinks).
126 Q_INVOKABLE bool linkDavAccount(const QString &davAccountId, const QString &mailAccountId);
127 // The backend reports changes of the active account's connection/rules.
128 902 void notifyOverviewChanged() { emit accountOverviewChanged(); }
129 11 AccountServiceCheck *serviceCheck() { return &m_serviceCheck; }
130 145 AccountSetupSession *setup() { return &m_setup; }
131 // A DAV account was created or its selection changed outside the editors:
132 // re-read the settings and start the calendar sync.
133 void notifyDavChanged(const QString &davAccountId);
134 // Sprint 100 S100.4.5 (SJ2): calendars and contacts with the login of a
135 // mail account — the stored incoming password is reused, never typed
136 // again. fields: mailAccountId, serverUrl, username. Returns {ok,
137 // requestId}; davAccountSaveFinished follows.
138 Q_INVOKABLE QVariantMap saveDavWithMailLogin(const QVariantMap &fields);
139
140 signals:
141 void accountSaveFinished(const QString &requestId, const QVariantMap &result);
142 void davAccountSaveFinished(const QString &requestId, const QVariantMap &result);
143 void imagePolicyModeChanged();
144 void defaultReadingModeChanged();
145 // D3 DAV group: DAV account list or the CalDAV interval changed.
146 void davSettingsChanged();
147 void accountOverviewChanged();
148
149 private:
150 MailSessionCore &m_session;
151 WorkspaceState &m_workspace;
152 QuickPreferences &m_preferences;
153 QuickPimBackend &m_pim;
154 const QString &m_profileDirectory; // owned by QuickMailBackend
155 Deps m_deps;
156 ExternalWhitelistModel *m_whitelist;
157 DavCollectionDiscovery m_davDiscovery{this};
158 DavServerHints m_serverHints{this};
159 AccountConnectionTest m_connectionTest{this};
160 DavConnectionTest m_davConnectionTest{this};
161 QHash<QString, QPointer<QObject>> m_settingsRequests;
162 AccountServiceCheck m_serviceCheck;
163 AccountSetupSession m_setup;
164 };
165