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

presentation/ComposeSessionStore.h
Line Branch Exec Source
1 #pragma once
2
3 #include "ComposeSession.h"
4
5 #include <QAbstractListModel>
6 #include <QHash>
7 #include <QPointer>
8 #include <memory>
9 #include <vector>
10
11 // Sprint 108 S108.9.1 (D-3, §4.3b): every open composer of this profile —
12 // new mails in tabs, replies inline in a reader, drafts in windows — and
13 // the drafts that wait in the undo window after *Send*. The list feeds the
14 // compose tabs and the status line's *open drafts* chip; sessions survive a
15 // restart through their draft directories (ComposeDraftFiles).
16 class ComposeSessionStore : public QAbstractListModel {
17 Q_OBJECT
18 Q_PROPERTY(int count READ rowCountProperty NOTIFY changed)
19 Q_PROPERTY(int openDrafts READ openDrafts NOTIFY changed)
20
21 public:
22 enum Roles { SessionRole = Qt::UserRole + 1, SessionIdRole, TitleRole, PlaceRole, KindRole, DirtyRole };
23
24 explicit ComposeSessionStore(QObject *parent = nullptr);
25 ~ComposeSessionStore() override;
26
27 int rowCount(const QModelIndex &parent = {}) const override;
28 QVariant data(const QModelIndex &index, int role) const override;
29 QHash<int, QByteArray> roleNames() const override;
30 1161 int rowCountProperty() const { return int(m_sessions.size()); }
31 int openDrafts() const;
32
33 // The dependencies every new session gets (the backend sets them).
34 798 void setDeps(ComposeSession::Deps deps) { m_deps = std::move(deps); }
35 const ComposeSession::Deps &deps() const { return m_deps; }
36
37 // A new composer: kind new/reply/replyAll/forward/resumed; place tab,
38 // inline or window; for inline replies the mail it belongs to.
39 ComposeSession *create(const QString &kind, const QVariantMap &prefill, const QString &place,
40 const QVariantMap &mailReference = {}, const ComposeSession::Quote &quote = {});
41 Q_INVOKABLE QObject *createSession(const QString &kind, const QVariantMap &prefill, const QString &place);
42 Q_INVOKABLE QObject *session(const QString &sessionId) const;
43 // The inline reply of a mail (§4.12: a second reply focuses the first).
44 Q_INVOKABLE QObject *sessionForMail(const QString &accountId, qint64 folderId, qint64 uid) const;
45 // The same for a workspace selection map ({accountId, folderId, uid} as
46 // strings: UIDs beyond 2^53 lose precision as JavaScript numbers).
47 Q_INVOKABLE QObject *sessionForReference(const QVariantMap &reference) const;
48 Q_INVOKABLE void setPlace(const QString &sessionId, const QString &place);
49 Q_INVOKABLE QString sessionIdAt(int row) const;
50 // The bin (D-28): the session leaves its place at once but its draft
51 // stays for the undo window; *Undo* brings it back where it was, the
52 // end of the window deletes the draft (local and server copy).
53 Q_INVOKABLE void discardWithUndo(const QString &sessionId, int undoMilliseconds = 8000);
54 Q_INVOKABLE QObject *undoDiscard();
55 // Quit and account switch: every open session writes its draft now;
56 // false when one of them could not be written.
57 Q_INVOKABLE bool saveAll();
58 // Quit: the discard in its undo window becomes final.
59
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 795 times.
795 void flushDiscard() { if (!m_discardedId.isEmpty()) finishDiscard(); }
60 QList<ComposeSession *> sessions() const;
61
62 // Restore after a restart: every saved draft that was open.
63 int restoreOpenSessions();
64 // The mail an inline reply belongs to left the view: the draft moves into
65 // a window (D-3) and the session says why.
66 void mailLeft(const QString &accountId, qint64 folderId, qint64 uid);
67
68 // Outbox hand-over: the session waits (hidden) while its message is in the
69 // undo window; *Undo* brings it back, transmission ends it.
70 void parkForOutbox(ComposeSession *session, qint64 outboxId);
71 ComposeSession *reopenFromOutbox(qint64 outboxId);
72 void outboxFinished(qint64 outboxId);
73 // Outbox *Delete*: the waiting message and its draft go, without reopening.
74 bool discardFromOutbox(qint64 outboxId);
75
76 signals:
77 void changed();
78 void sessionOpened(QObject *session);
79 void sessionReopened(QObject *session);
80 void sessionClosed(const QString &sessionId, const QString &reason);
81
82 private:
83 ComposeSession::Deps m_deps;
84 std::vector<std::unique_ptr<ComposeSession>> m_sessions;
85 QHash<qint64, QString> m_outboxSessions; // outbox id → parked session id
86 QString m_discardedId; // the session in its discard undo window
87 QString m_discardedPlace;
88 QVariantMap m_discardedReference;
89 void finishDiscard();
90 void adopt(std::unique_ptr<ComposeSession> session);
91 void removeSession(const QString &sessionId, bool deleteDraft);
92 int indexOf(const QString &sessionId) const;
93 };
94