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: 93.3% 14 / 0 / 15
Functions: 93.3% 14 / 0 / 15
Branches: -% 0 / 0 / 0

presentation/AccountSetupSession.h
Line Branch Exec Source
1 #pragma once
2 #include "AccountServiceCheck.h"
3 #include "service/MailServerDiscovery.h"
4 #include <QObject>
5 #include <QPointer>
6 #include <QVariantMap>
7 #include <functional>
8
9 class QuickAccountSettings;
10 struct CalendarInfo;
11 struct AddressBookInfo;
12
13 // Sprint 100 S100.1.9 (D-6, §6.2.2, SJ1, SJ2): the guided setup.
14 // address → discovering → [review] → testing → [outgoing] → services → done
15 // ↘ manual (nothing or only part found) ↘ failed
16 // begin() takes name, address and password; the servers are found without
17 // the password (MailServerDiscovery), shown when they are not the
18 // provider's own (review), then the login is checked (AccountServiceCheck:
19 // IMAP login and SMTP AUTH). The account is saved through the normal async
20 // save with "same login" for outgoing mail (D-17). Calendars and contacts
21 // of the same provider are then looked for with the same login (RFC 6764
22 // well-known addresses) and, at finish(), saved as a linked DAV account
23 // with the D-20 default selection (SB-07 cannot happen here).
24 // The password lives only in this object while the setup runs.
25 class AccountSetupSession final : public QObject {
26 5 Q_OBJECT
27 Q_PROPERTY(QString state READ state NOTIFY changed)
28 Q_PROPERTY(QString address READ address NOTIFY changed)
29 Q_PROPERTY(QVariantMap sources READ sources NOTIFY changed)
30 Q_PROPERTY(QVariantMap servers READ servers NOTIFY changed)
31 Q_PROPERTY(QVariantMap incoming READ incoming NOTIFY changed)
32 Q_PROPERTY(QVariantMap outgoing READ outgoing NOTIFY changed)
33 Q_PROPERTY(QString message READ message NOTIFY changed)
34 Q_PROPERTY(QString accountId READ accountId NOTIFY changed)
35 // "idle", "searching", "confirm", "found", "none"
36 Q_PROPERTY(QString davState READ davState NOTIFY changed)
37 // The derived host that answered 401 and waits for the user's explicit
38 // credential approval (F-23); set while davState is "confirm".
39 Q_PROPERTY(QString davHost READ davHost NOTIFY changed)
40 // [{key, name, kind ("calendar", "tasks", "both", "book"), selected, reason}]
41 Q_PROPERTY(QVariantList collections READ collections NOTIFY changed)
42 Q_PROPERTY(bool busy READ busy NOTIFY changed)
43 public:
44 // authRequired: the host answered 401 — it is a DAV host that wants the
45 // login. The session asks before it sends credentials to a derived host
46 // (F-23); probes of a host the provider's autoconfig named send them
47 // directly.
48 using DavProbe = std::function<void(QObject *owner, const QString &serverUrl, const QString &username,
49 const QByteArray &password,
50 std::function<void(bool ok, QList<CalendarInfo>, QList<AddressBookInfo>, bool authRequired)>)>;
51 // Starts the async save of the account fields: {ok, requestId} or {ok:
52 // false, error}; accountSaveFinished(requestId) of the settings follows.
53 using AccountSaver = std::function<QVariantMap(const QVariantMap &fields)>;
54 explicit AccountSetupSession(QuickAccountSettings *settings, AccountSession *accounts, QObject *parent = nullptr);
55 ~AccountSetupSession() override;
56 // Test seams: replayed discovery, login check, DAV lookup.
57 7 MailServerDiscovery *discovery() { return &m_discovery; }
58 2 AccountServiceCheck *serviceCheck() { return &m_check; }
59 3 void setDavProbe(DavProbe probe) { m_davProbe = std::move(probe); }
60 5 void setAccountSaver(AccountSaver saver) { m_saver = std::move(saver); }
61
62 54 QString state() const { return m_state; }
63 2 QString address() const { return m_address; }
64 8 QVariantMap sources() const { return m_discovery.sources(); }
65 6 QVariantMap servers() const { return m_servers; }
66 1 QVariantMap incoming() const { return m_incoming; }
67 1 QVariantMap outgoing() const { return m_outgoing; }
68 4 QString message() const { return m_message; }
69 ✗ QString accountId() const { return m_accountId; }
70 40 QString davState() const { return m_davState; }
71 4 QString davHost() const { return m_davHost; }
72 QVariantList collections() const;
73 bool busy() const;
74
75 // {provider, name, helpUrl} for an address being typed (Google, Microsoft,
76 // Apple need app passwords, T-036).
77 Q_INVOKABLE QVariantMap providerHint(const QString &address) const;
78 // Returns "" or the reason the address cannot be used (field "email").
79 Q_INVOKABLE QString begin(const QString &name, const QString &address, const QString &password);
80 Q_INVOKABLE void lookupIspdb();
81 Q_INVOKABLE void useServers();
82 // The manual editor: imapHost/Port/Security, smtpHost/Port/Security,
83 // username, smtpLogin, smtpUsername, smtpPassword.
84 Q_INVOKABLE void useManual(const QVariantMap &fields);
85 Q_INVOKABLE void retry(const QString &password);
86 Q_INVOKABLE void continueWithoutSending();
87 Q_INVOKABLE void setCollection(const QString &key, bool selected);
88 // F-23: explicit answers to the credential question of a derived host.
89 Q_INVOKABLE void authorizeDavHost();
90 Q_INVOKABLE void skipDavHost();
91 Q_INVOKABLE void finish(bool withCalendars);
92 Q_INVOKABLE void cancel();
93
94 signals:
95 void changed();
96 void done(const QString &accountId);
97
98 private:
99 void setState(const QString &state, const QString &message = {});
100 void discoveryFinished(bool found);
101 void check();
102 void checked(const QVariantMap &result);
103 void save();
104 void saved(const QVariantMap &result);
105 void findCalendars();
106 void tryDav(int index, bool withCredentials);
107 QVariantMap accountFields() const;
108 QuickAccountSettings *m_settings;
109 AccountSession *m_accounts;
110 MailServerDiscovery m_discovery;
111 AccountServiceCheck m_check;
112 DavProbe m_davProbe;
113 AccountSaver m_saver;
114 QString m_state = QStringLiteral("address");
115 QString m_name, m_address, m_message, m_accountId;
116 QByteArray m_password;
117 QVariantMap m_servers, m_incoming, m_outgoing;
118 bool m_skipOutgoing = false;
119 QString m_checkId, m_saveId;
120 QString m_davState = QStringLiteral("idle");
121 QString m_davServer;
122 QStringList m_davCandidates;
123 // F-23: candidates below m_davTrustedCount are derived from the mail
124 // domain (bare domain, dav.<domain>) and are probed without credentials
125 // first; the rest were named by the provider's autoconfig (the IMAP
126 // host) and already receive the mail login.
127 int m_davTrustedCount = 0;
128 int m_davIndex = 0;
129 QString m_davHost;
130 struct Collection { QString key, name, kind, reason; bool selected = true; bool calendar = true; };
131 QList<Collection> m_collections;
132 QPointer<QObject> m_davRun;
133 };
134