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

presentation/QuickInvitation.h
Line Branch Exec Source
1 #pragma once
2
3 #include "data/ImipInvitation.h"
4 #include "data/MailRequest.h"
5
6 #include <QObject>
7 #include <QVariantList>
8 #include <QVariantMap>
9 #include <functional>
10 #include <optional>
11
12 class MailSessionCore;
13
14 // Sprint 93 S93.5.2 (CAL-IMIP, D-3): the invitation card of the displayed
15 // mail. QML reaches it as `backend.invitation`.
16 //
17 // The host reports the displayed mail and its attachments (setMail). The
18 // first text/calendar or .ics attachment is read (bounded window) and
19 // parsed; `card` then describes it for InvitationCard.qml:
20 // method, state, title, whenText, zoneText, location, meetingUrl,
21 // organizer, attendees [{name, email, status, me}], rrule, startIso,
22 // dateIso, conflicts [text], changes [field], myStatus, inCalendar,
23 // calendarName, canReply, replyAs, serverSends, comment, replier,
24 // replierStatus, calendars [{key, displayName, color}], defaultCalendar.
25 // state: "new" (not stored yet), "answered", "updated" (newer SEQUENCE than
26 // the stored copy), "outdated" (older), "cancelled", "reply" (an attendee
27 // answered an own appointment), "counter" (display only), "publish" (a
28 // calendar file without attendees to answer).
29 //
30 // Answers store the invitation through the CalendarSyncCoordinator (the raw
31 // resource, so nothing is lost) with the user's PARTSTAT and send the iMIP
32 // REPLY from the active account — unless the DAV server schedules
33 // (RFC 6638 schedule-outbox-URL discovered, or the "server sends replies"
34 // setting), which then sends the reply itself.
35 class QuickInvitation final : public QObject {
36 135 Q_OBJECT
37 Q_PROPERTY(bool active READ active NOTIFY changed)
38 Q_PROPERTY(QVariantMap card READ card NOTIFY changed)
39 // Who answers invitations: "auto", "client" or "server" (see below).
40 Q_PROPERTY(QString replyMode READ replyMode WRITE setReplyMode NOTIFY changed)
41 public:
42 struct Deps {
43 std::function<QVariantList()> calendarChoices; // QuickPimBackend::calendarChoices
44 std::function<QString()> lastCalendar; // "accountId\npath"
45 std::function<bool(const QStringList &recipients, const QByteArray &message,
46 const QString &doneText)> send;
47 std::function<void(const QString &)> setStatus;
48 };
49 QuickInvitation(MailSessionCore &session, Deps deps, QObject *parent = nullptr);
50
51 1565 bool active() const { return m_invitation.has_value(); }
52 47 QVariantMap card() const { return m_card; }
53
54 // The displayed mail changed or its attachments arrived. Cheap when
55 // nothing changed (same mail and attachment).
56 void setMail(const MailId &mail, const QVariantList &attachments, const QString &from = {});
57 // Shows calendar text directly (tests, the bytes of setMail's read).
58 void showCalendarText(const QString &text);
59
60 // partstat: ACCEPTED, TENTATIVE or DECLINED. calendarKey from
61 // card.calendars ("" = card.defaultCalendar); the stored copy's calendar
62 // wins for an invitation that is already in the calendar.
63 Q_INVOKABLE bool respond(const QString &partstat, const QString &calendarKey,
64 const QString &comment, bool confirmMismatch = false);
65 // PUBLISH / an update without a new answer: store as is.
66 Q_INVOKABLE bool addToCalendar(const QString &calendarKey, bool confirmMismatch = false);
67 // CANCEL: removes the stored appointment.
68 Q_INVOKABLE bool removeFromCalendar(bool confirmMismatch = false);
69 // REPLY: stores the attendee's new status in the own appointment.
70 Q_INVOKABLE bool applyReply(bool confirmMismatch = false);
71
72 // "auto" (server decides by its scheduling support), "client" (MailJD
73 // always sends replies) or "server" (never sends replies); QSettings
74 // "calendar/imipReplies".
75 QString replyMode() const;
76 void setReplyMode(const QString &mode);
77
78 signals:
79 void changed();
80
81 private:
82 struct Stored {
83 QString accountId, calendarPath;
84 CalendarEvent master;
85 };
86 std::optional<Stored> storedCopy() const;
87 QStringList ownAddresses() const;
88 QString ownAddress() const; // the attendee address the user answers as
89 bool serverSends(const QString &accountId) const;
90 bool resolveCalendar(const QString &key, QString *accountId, QString *path) const;
91 QStringList conflicts() const;
92 QVariantList attendeeList(const QString &me) const;
93 void rebuildCard();
94 void clear();
95 bool storeRows(const QString &accountId, const QString &path, const QString &partstat);
96 bool admitsMutation(bool confirmMismatch);
97
98 MailSessionCore &m_session;
99 Deps m_deps;
100 MailId m_mail;
101 qint64 m_attachmentId = 0;
102 quint64 m_readGeneration = 0;
103 std::optional<Imip::Invitation> m_invitation;
104 QVariantMap m_card;
105 QString m_mailFrom;
106 QString m_mailSender;
107 bool m_replyAutoApplied = false; // S108.8.7: this card's REPLY was applied without a click
108 void applyReplyAutomatically();
109 };
110