presentation/QuickDavPush.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "QuickDavPush.h" | ||
| 2 | |||
| 3 | #include "app/core/CalendarSyncCoordinator.h" | ||
| 4 | #include "app/core/CalendarSyncStatus.h" | ||
| 5 | #include "app/core/DavPushStatistics.h" | ||
| 6 | #include "app/core/DavSyncScheduler.h" | ||
| 7 | #include "data/CalendarStore.h" | ||
| 8 | #include "data/DavPushSettings.h" | ||
| 9 | #include "data/DavPushStore.h" | ||
| 10 | #include "service/DavPushServiceTest.h" | ||
| 11 | |||
| 12 | #include <QClipboard> | ||
| 13 | #include <QPointer> | ||
| 14 | #include <QDateTime> | ||
| 15 | #include <QGuiApplication> | ||
| 16 | #include <QLocale> | ||
| 17 | #include <QLoggingCategory> | ||
| 18 | #include <QUrl> | ||
| 19 | #include <algorithm> | ||
| 20 | |||
| 21 |
4/7✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 8 taken 15 times.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
17 | Q_LOGGING_CATEGORY(lcQuickPush, "mailjd.quick.push") |
| 22 | |||
| 23 | namespace { | ||
| 24 | constexpr int kIconPaused = 0xF03E6; // pause-circle-outline | ||
| 25 | constexpr int kIconOffline = 0xF0164; // cloud-off-outline | ||
| 26 | constexpr int kIconSyncAlert = 0xF04E7; // sync-alert | ||
| 27 | constexpr int kIconInterrupted = 0xF0E81; // bell-alert-outline | ||
| 28 | constexpr int kIconSetup = 0xF009C; // bell-outline | ||
| 29 | constexpr int kIconWaiting = 0xF051F; // timer-sand | ||
| 30 | constexpr int kIconConnecting = 0xF031A; // lan-pending | ||
| 31 | constexpr int kIconActive = 0xF140C; // lightning-bolt-outline (F100-05: quiet, "instant") | ||
| 32 | constexpr int kIconNoPush = 0xF0A91; // bell-off-outline | ||
| 33 | constexpr int kIconOff = 0xF13E8; // bell-cancel-outline | ||
| 34 | |||
| 35 | 29 | bool credentialsKind(const QString &kind) { | |
| 36 |
4/6✓ Branch 4 → 5 taken 28 times.
✓ Branch 4 → 11 taken 1 time.
✓ Branch 7 → 8 taken 28 times.
✗ Branch 7 → 11 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 28 times.
|
57 | return kind == QLatin1String("password") || kind == QLatin1String("authorization") || |
| 37 | 57 | kind == QLatin1String("authentication"); | |
| 38 | } | ||
| 39 | |||
| 40 | 4 | QPair<qint64, qint64> medianP95(QList<qint64> values) { | |
| 41 |
2/2✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 7 taken 2 times.
|
4 | if (values.isEmpty()) return {-1, -1}; |
| 42 |
3/3✓ Branch 7 → 8 taken 2 times.
✓ Branch 8 → 9 taken 2 times.
✓ Branch 9 → 10 taken 2 times.
|
2 | std::sort(values.begin(), values.end()); |
| 43 | 4 | const auto at = [&](double q) { return values.at(qMin<qsizetype>(values.size() - 1, qsizetype(q * values.size()))); }; | |
| 44 | 2 | return {at(0.5), at(0.95)}; | |
| 45 | } | ||
| 46 | } // namespace | ||
| 47 | |||
| 48 | // --- model ------------------------------------------------------------------ | ||
| 49 | |||
| 50 | 397 | int QuickDavPushModel::rowCount(const QModelIndex &parent) const { | |
| 51 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 397 times.
|
397 | return parent.isValid() ? 0 : int(m_rows.size()); |
| 52 | } | ||
| 53 | |||
| 54 | 218 | QVariant QuickDavPushModel::data(const QModelIndex &index, int role) const { | |
| 55 |
3/6✓ Branch 3 → 4 taken 218 times.
✗ Branch 3 → 7 not taken.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 218 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 218 times.
|
218 | if (!index.isValid() || index.row() >= m_rows.size()) return {}; |
| 56 | 218 | const DavPushRow &row = m_rows.at(index.row()); | |
| 57 |
7/13✓ Branch 13 → 14 taken 48 times.
✗ Branch 13 → 15 not taken.
✗ Branch 13 → 16 not taken.
✓ Branch 13 → 17 taken 48 times.
✓ Branch 13 → 18 taken 24 times.
✓ Branch 13 → 19 taken 24 times.
✓ Branch 13 → 20 taken 1 time.
✓ Branch 13 → 21 taken 48 times.
✗ Branch 13 → 22 not taken.
✗ Branch 13 → 23 not taken.
✗ Branch 13 → 24 not taken.
✓ Branch 13 → 25 taken 25 times.
✗ Branch 13 → 26 not taken.
|
218 | switch (role) { |
| 58 | 48 | case KeyRole: return row.key; | |
| 59 | ✗ | case AccountIdRole: return row.accountId; | |
| 60 | ✗ | case PathRole: return row.path; | |
| 61 | 48 | case DisplayNameRole: return row.displayName; | |
| 62 | 24 | case AccountLabelRole: return row.accountLabel; | |
| 63 | 24 | case AutomaticRole: return row.automatic; | |
| 64 | 1 | case StateKeyRole: return row.stateKey; | |
| 65 | 48 | case StateTextRole: return row.stateText; | |
| 66 | ✗ | case SeverityRole: return row.severity; | |
| 67 | ✗ | case IconRole: return row.icon; | |
| 68 | ✗ | case DetailTextRole: return row.detailText; | |
| 69 | 25 | case KindRole: return row.kind; | |
| 70 | ✗ | default: return {}; | |
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | 8 | QHash<int, QByteArray> QuickDavPushModel::roleNames() const { | |
| 75 | ✗ | return {{KeyRole, "calendarKey"}, {AccountIdRole, "accountId"}, {PathRole, "calendarPath"}, | |
| 76 | ✗ | {DisplayNameRole, "displayName"}, {AccountLabelRole, "accountLabel"}, {AutomaticRole, "automatic"}, | |
| 77 | ✗ | {StateKeyRole, "stateKey"}, {StateTextRole, "stateText"}, {SeverityRole, "severity"}, | |
| 78 |
2/4✓ Branch 16 → 17 taken 96 times.
✓ Branch 16 → 18 taken 8 times.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
|
104 | {IconRole, "icon"}, {DetailTextRole, "detailText"}, {KindRole, "kind"}}; |
| 79 | 8 | } | |
| 80 | |||
| 81 | 987 | void QuickDavPushModel::setRows(const QList<DavPushRow> &rows) { | |
| 82 | 987 | bool sameKeys = rows.size() == m_rows.size(); | |
| 83 |
6/6✓ Branch 9 → 10 taken 985 times.
✓ Branch 9 → 13 taken 76 times.
✓ Branch 11 → 12 taken 74 times.
✓ Branch 11 → 13 taken 911 times.
✓ Branch 14 → 5 taken 74 times.
✓ Branch 14 → 15 taken 987 times.
|
1061 | for (qsizetype i = 0; sameKeys && i < rows.size(); ++i) sameKeys = rows.at(i).key == m_rows.at(i).key; |
| 84 |
2/2✓ Branch 15 → 16 taken 76 times.
✓ Branch 15 → 20 taken 911 times.
|
987 | if (!sameKeys) { |
| 85 | 76 | beginResetModel(); | |
| 86 | 76 | m_rows = rows; | |
| 87 | 76 | endResetModel(); | |
| 88 | 76 | return; | |
| 89 | } | ||
| 90 |
2/2✓ Branch 39 → 21 taken 74 times.
✓ Branch 39 → 40 taken 911 times.
|
985 | for (qsizetype i = 0; i < rows.size(); ++i) { |
| 91 |
2/2✓ Branch 24 → 25 taken 53 times.
✓ Branch 24 → 26 taken 21 times.
|
74 | if (rows.at(i) == m_rows.at(i)) continue; |
| 92 | 21 | m_rows[i] = rows.at(i); | |
| 93 |
3/3✓ Branch 31 → 32 taken 21 times.
✓ Branch 33 → 34 taken 21 times.
✓ Branch 34 → 35 taken 21 times.
|
21 | emit dataChanged(index(int(i)), index(int(i))); |
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | // --- derivation --------------------------------------------------------------- | ||
| 98 | |||
| 99 | 230 | DavPushRow QuickDavPush::deriveRow(const DavPushCollectionStatus &status, const DavPushRowContext &context) { | |
| 100 | 230 | DavPushRow row; | |
| 101 |
1/1✓ Branch 2 → 3 taken 230 times.
|
230 | row.key = calendarSelectionKey(status.accountId, status.path); |
| 102 |
4/4✓ Branch 6 → 7 taken 90 times.
✓ Branch 6 → 10 taken 140 times.
✓ Branch 13 → 14 taken 90 times.
✓ Branch 13 → 15 taken 140 times.
|
320 | row.kind = status.kind.isEmpty() ? QStringLiteral("calendar") : status.kind; |
| 103 | 230 | const bool book = row.kind == QLatin1String("addressbook"); | |
| 104 | 230 | row.accountId = status.accountId; | |
| 105 | 230 | row.path = status.path; | |
| 106 | 230 | row.displayName = status.displayName; | |
| 107 | 230 | row.accountLabel = status.accountLabel; | |
| 108 | 230 | row.automatic = status.policy == DavPushPolicy::Automatic; | |
| 109 | 241 | const auto set = [&row](const char *key, const QString &text, const char *severity, int icon, const QString &detail) { | |
| 110 |
1/1✓ Branch 3 → 4 taken 241 times.
|
241 | row.stateKey = QLatin1String(key); |
| 111 | 241 | row.stateText = text; | |
| 112 |
1/1✓ Branch 6 → 7 taken 241 times.
|
241 | row.severity = QLatin1String(severity); |
| 113 | 241 | row.icon = icon; | |
| 114 | 241 | row.detailText = detail; | |
| 115 | 241 | }; | |
| 116 |
1/1✓ Branch 21 → 22 taken 230 times.
|
230 | const QString interval = tr("MailJD keeps synchronizing every %n minute(s).", "", context.intervalMinutes); |
| 117 | // (1) explicit pause / offline | ||
| 118 |
2/2✓ Branch 24 → 25 taken 97 times.
✓ Branch 24 → 31 taken 133 times.
|
230 | if (status.pauseReason == QLatin1String("offline")) { |
| 119 |
2/2✓ Branch 26 → 27 taken 97 times.
✓ Branch 27 → 28 taken 97 times.
|
97 | set("offline", tr("Offline · sync paused"), "paused", kIconOffline, |
| 120 |
1/1✓ Branch 25 → 26 taken 97 times.
|
194 | tr("MailJD is offline. Changes are synchronized when the connection is back.")); |
| 121 |
6/6✓ Branch 33 → 34 taken 130 times.
✓ Branch 33 → 37 taken 3 times.
✓ Branch 36 → 37 taken 2 times.
✓ Branch 36 → 38 taken 128 times.
✓ Branch 39 → 40 taken 5 times.
✓ Branch 39 → 50 taken 128 times.
|
133 | } else if (status.pauseReason == QLatin1String("background-off") || status.pauseReason == QLatin1String("suspended")) { |
| 122 |
2/2✓ Branch 45 → 46 taken 5 times.
✓ Branch 46 → 47 taken 5 times.
|
5 | set("paused", tr("Automatic sync paused"), "paused", kIconPaused, |
| 123 | 5 | status.pauseReason == QLatin1String("suspended") | |
| 124 |
4/4✓ Branch 42 → 43 taken 2 times.
✓ Branch 42 → 44 taken 3 times.
✓ Branch 43 → 45 taken 2 times.
✓ Branch 44 → 45 taken 3 times.
|
10 | ? tr("The computer is going to sleep; synchronization continues after waking up.") |
| 125 | : tr("Automatic synchronization is switched off (interval 0). Use Sync now.")); | ||
| 126 | // (2) data sync error or local conflict | ||
| 127 |
2/2✓ Branch 51 → 52 taken 4 times.
✓ Branch 51 → 58 taken 124 times.
|
128 | } else if (!context.accountSyncError.isEmpty()) { |
| 128 |
2/2✓ Branch 53 → 54 taken 4 times.
✓ Branch 54 → 55 taken 4 times.
|
4 | set("sync-error", tr("Sync failed"), "error", kIconSyncAlert, |
| 129 |
1/1✓ Branch 52 → 53 taken 4 times.
|
8 | CalendarSyncStatus::messageForKind(context.accountSyncError)); |
| 130 |
4/4✓ Branch 58 → 59 taken 120 times.
✓ Branch 58 → 60 taken 4 times.
✓ Branch 59 → 60 taken 2 times.
✓ Branch 59 → 68 taken 118 times.
|
124 | } else if (context.conflicts > 0 || context.pendingWrites > 0) { |
| 131 |
2/2✓ Branch 63 → 64 taken 6 times.
✓ Branch 64 → 65 taken 6 times.
|
6 | set("conflict", tr("Local changes waiting"), "warning", kIconSyncAlert, |
| 132 |
3/3✓ Branch 60 → 61 taken 4 times.
✓ Branch 60 → 62 taken 2 times.
✓ Branch 61 → 63 taken 4 times.
|
12 | context.conflicts > 0 ? tr("%n change(s) need a decision.", "", context.conflicts) |
| 133 |
1/1✓ Branch 62 → 63 taken 2 times.
|
2 | : tr("%n local change(s) are not on the server yet.", "", context.pendingWrites)); |
| 134 | // push not wanted / not offered (settings and capability, not failures) | ||
| 135 |
4/4✓ Branch 68 → 69 taken 114 times.
✓ Branch 68 → 70 taken 4 times.
✓ Branch 69 → 70 taken 11 times.
✓ Branch 69 → 74 taken 103 times.
|
118 | } else if (!context.pushEnabled || status.policy == DavPushPolicy::IntervalOnly) { |
| 136 |
2/2✓ Branch 70 → 71 taken 15 times.
✓ Branch 71 → 72 taken 15 times.
|
15 | set("off", tr("Push off · interval sync"), "neutral", kIconOff, interval); |
| 137 |
2/2✓ Branch 74 → 75 taken 7 times.
✓ Branch 74 → 79 taken 96 times.
|
103 | } else if (status.offer.capability == DavPushCapability::Unsupported) { |
| 138 |
2/2✓ Branch 75 → 76 taken 7 times.
✓ Branch 76 → 77 taken 7 times.
|
7 | set("unsupported", tr("Server offers no push"), "neutral", kIconNoPush, interval); |
| 139 |
2/2✓ Branch 79 → 80 taken 2 times.
✓ Branch 79 → 88 taken 94 times.
|
96 | } else if (status.offer.capability == DavPushCapability::Incompatible) { |
| 140 |
2/2✓ Branch 82 → 83 taken 2 times.
✓ Branch 83 → 84 taken 2 times.
|
2 | set("unsupported", tr("Server offers no usable push"), "neutral", kIconNoPush, |
| 141 |
2/2✓ Branch 80 → 81 taken 2 times.
✓ Branch 81 → 82 taken 2 times.
|
4 | tr("The server offers push in a form MailJD cannot use (%1). %2").arg(status.offer.reason, interval)); |
| 142 |
2/2✓ Branch 88 → 89 taken 27 times.
✓ Branch 88 → 97 taken 67 times.
|
94 | } else if (status.offer.capability != DavPushCapability::Supported) { |
| 143 |
2/2✓ Branch 92 → 93 taken 27 times.
✓ Branch 93 → 94 taken 27 times.
|
27 | set("checking", tr("Checking push…"), "info", kIconWaiting, |
| 144 |
4/4✓ Branch 89 → 90 taken 1 time.
✓ Branch 89 → 91 taken 26 times.
✓ Branch 90 → 92 taken 1 time.
✓ Branch 91 → 92 taken 26 times.
|
54 | book ? tr("MailJD checks whether the server offers push for this address book.") |
| 145 | : tr("MailJD checks whether the server offers push for this calendar.")); | ||
| 146 | // (3) push failure with fallback | ||
| 147 |
2/2✓ Branch 97 → 98 taken 65 times.
✓ Branch 97 → 119 taken 2 times.
|
67 | } else if (context.receiverConfigured && |
| 148 |
4/4✓ Branch 98 → 99 taken 53 times.
✓ Branch 98 → 101 taken 12 times.
✓ Branch 99 → 100 taken 50 times.
✓ Branch 99 → 101 taken 3 times.
|
65 | (status.receiver == DavPushReceiverState::Backoff || status.receiver == DavPushReceiverState::Failed || |
| 149 |
2/2✓ Branch 100 → 101 taken 2 times.
✓ Branch 100 → 119 taken 48 times.
|
50 | status.registration == DavPushRegistrationState::Failed)) { |
| 150 |
2/2✓ Branch 102 → 103 taken 3 times.
✓ Branch 102 → 105 taken 2 times.
|
5 | const QString cause = status.receiver == DavPushReceiverState::Backoff || status.receiver == DavPushReceiverState::Failed |
| 151 |
2/2✓ Branch 101 → 102 taken 5 times.
✓ Branch 101 → 103 taken 12 times.
|
17 | ? tr("The push service does not respond.") |
| 152 |
2/2✓ Branch 103 → 104 taken 15 times.
✓ Branch 105 → 106 taken 2 times.
|
17 | : tr("The server did not accept the push subscription."); |
| 153 |
2/2✓ Branch 111 → 112 taken 17 times.
✓ Branch 112 → 113 taken 17 times.
|
17 | set("interrupted", tr("Push interrupted · interval sync active"), "warning", kIconInterrupted, |
| 154 |
3/3✓ Branch 106 → 107 taken 17 times.
✓ Branch 109 → 110 taken 17 times.
✓ Branch 110 → 111 taken 17 times.
|
34 | cause + QLatin1Char(' ') + tr("MailJD keeps syncing at the interval.")); |
| 155 | // (4) setup / connection needed | ||
| 156 |
2/2✓ Branch 119 → 120 taken 2 times.
✓ Branch 119 → 128 taken 48 times.
|
67 | } else if (!context.receiverConfigured) { |
| 157 |
2/2✓ Branch 123 → 124 taken 2 times.
✓ Branch 124 → 125 taken 2 times.
|
2 | set("setup", tr("Set up a push service"), "info", kIconSetup, |
| 158 |
4/4✓ Branch 120 → 121 taken 1 time.
✓ Branch 120 → 122 taken 1 time.
✓ Branch 121 → 123 taken 1 time.
✓ Branch 122 → 123 taken 1 time.
|
4 | book ? tr("This address book supports push. Choose a push service in the DAV settings.") |
| 159 | : tr("This calendar supports push. Choose a push service in the DAV settings.")); | ||
| 160 |
2/2✓ Branch 128 → 129 taken 37 times.
✓ Branch 128 → 145 taken 11 times.
|
48 | } else if (status.registration == DavPushRegistrationState::Active && |
| 161 |
1/2✓ Branch 129 → 130 taken 37 times.
✗ Branch 129 → 145 not taken.
|
37 | status.receiver == DavPushReceiverState::Connected) { |
| 162 | // (5) normal operation | ||
| 163 |
3/4✓ Branch 130 → 131 taken 12 times.
✓ Branch 130 → 133 taken 25 times.
✓ Branch 131 → 132 taken 12 times.
✗ Branch 131 → 133 not taken.
|
37 | const bool received = status.lastPushAt > 0 && status.lastPushAt * 1000 >= status.receiverConnectedSince; |
| 164 |
3/3✓ Branch 138 → 139 taken 12 times.
✓ Branch 138 → 140 taken 25 times.
✓ Branch 141 → 142 taken 37 times.
|
37 | set(received ? "active-received" : "active", |
| 165 |
4/4✓ Branch 135 → 136 taken 12 times.
✓ Branch 135 → 137 taken 25 times.
✓ Branch 136 → 138 taken 12 times.
✓ Branch 137 → 138 taken 25 times.
|
74 | received ? tr("Push active · change received") : tr("Push active"), "ok", kIconActive, |
| 166 |
1/1✓ Branch 134 → 135 taken 37 times.
|
74 | tr("Changes arrive within seconds while MailJD is running.")); |
| 167 | 37 | } else { | |
| 168 |
2/2✓ Branch 148 → 149 taken 11 times.
✓ Branch 149 → 150 taken 11 times.
|
11 | set("connecting", tr("Connecting push…"), "info", kIconConnecting, |
| 169 |
4/4✓ Branch 145 → 146 taken 1 time.
✓ Branch 145 → 147 taken 10 times.
✓ Branch 146 → 148 taken 1 time.
✓ Branch 147 → 148 taken 10 times.
|
22 | book ? tr("MailJD subscribes this address book and connects to the push service.") |
| 170 | : tr("MailJD subscribes this calendar and connects to the push service.")); | ||
| 171 | } | ||
| 172 |
8/8✓ Branch 153 → 154 taken 134 times.
✓ Branch 153 → 161 taken 96 times.
✓ Branch 156 → 157 taken 129 times.
✓ Branch 156 → 160 taken 5 times.
✓ Branch 159 → 160 taken 6 times.
✓ Branch 159 → 161 taken 123 times.
✓ Branch 162 → 163 taken 11 times.
✓ Branch 162 → 167 taken 219 times.
|
230 | if (status.lastSyncAt == 0 && (row.severity == QLatin1String("ok") || row.severity == QLatin1String("neutral"))) |
| 173 |
2/2✓ Branch 163 → 164 taken 11 times.
✓ Branch 164 → 165 taken 11 times.
|
11 | set("never", tr("Not synchronized yet"), "info", kIconWaiting, row.detailText); |
| 174 | 230 | return row; | |
| 175 | 230 | } | |
| 176 | |||
| 177 | // --- QuickDavPush --------------------------------------------------------- | ||
| 178 | |||
| 179 | 806 | QuickDavPush::QuickDavPush(DavPushCoordinator *coordinator, CalendarSyncCoordinator *calendar, QObject *parent) | |
| 180 |
5/5✓ Branch 3 → 4 taken 806 times.
✓ Branch 4 → 5 taken 806 times.
✓ Branch 5 → 6 taken 806 times.
✓ Branch 7 → 8 taken 806 times.
✓ Branch 8 → 9 taken 806 times.
|
1612 | : QObject(parent), m_coordinator(coordinator), m_calendar(calendar) { |
| 181 |
1/1✓ Branch 16 → 17 taken 806 times.
|
806 | m_coalesce.setSingleShot(true); |
| 182 |
1/1✓ Branch 17 → 18 taken 806 times.
|
806 | m_coalesce.setInterval(150); |
| 183 |
1/1✓ Branch 18 → 19 taken 806 times.
|
806 | connect(&m_coalesce, &QTimer::timeout, this, &QuickDavPush::refresh); |
| 184 |
1/1✓ Branch 20 → 21 taken 806 times.
|
806 | m_age.setInterval(30000); // relative texts age |
| 185 |
1/1✓ Branch 21 → 22 taken 806 times.
|
806 | connect(&m_age, &QTimer::timeout, this, &QuickDavPush::refresh); |
| 186 |
1/1✓ Branch 23 → 24 taken 806 times.
|
806 | m_age.start(); |
| 187 |
3/3✓ Branch 25 → 26 taken 796 times.
✓ Branch 25 → 31 taken 10 times.
✓ Branch 28 → 29 taken 796 times.
|
806 | if (m_coordinator) connect(m_coordinator, &DavPushCoordinator::changed, &m_coalesce, qOverload<>(&QTimer::start)); |
| 188 |
2/2✓ Branch 32 → 33 taken 795 times.
✓ Branch 32 → 47 taken 11 times.
|
806 | if (m_calendar) { |
| 189 |
1/1✓ Branch 35 → 36 taken 795 times.
|
795 | connect(m_calendar, &CalendarSyncCoordinator::syncStateChanged, &m_coalesce, qOverload<>(&QTimer::start)); |
| 190 |
1/1✓ Branch 40 → 41 taken 795 times.
|
795 | connect(m_calendar->syncStatus(), &CalendarSyncStatus::changed, &m_coalesce, qOverload<>(&QTimer::start)); |
| 191 |
1/1✓ Branch 44 → 45 taken 795 times.
|
795 | connect(m_calendar, &CalendarSyncCoordinator::storeChanged, &m_coalesce, qOverload<>(&QTimer::start)); |
| 192 | } | ||
| 193 |
1/1✓ Branch 47 → 48 taken 806 times.
|
806 | refresh(); |
| 194 | 806 | } | |
| 195 | |||
| 196 | 1601 | QuickDavPush::~QuickDavPush() = default; | |
| 197 | |||
| 198 | 69 | qint64 QuickDavPush::now() const { | |
| 199 |
2/2✓ Branch 3 → 4 taken 61 times.
✓ Branch 3 → 6 taken 8 times.
|
69 | return m_clock ? m_clock() : QDateTime::currentSecsSinceEpoch(); |
| 200 | } | ||
| 201 | |||
| 202 | 200 | DavPushRowContext QuickDavPush::contextFor(const DavPushCollectionStatus &status) const { | |
| 203 | 200 | DavPushRowContext context; | |
| 204 |
3/5✓ Branch 3 → 4 taken 118 times.
✓ Branch 3 → 8 taken 82 times.
✓ Branch 5 → 6 taken 118 times.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 70 not taken.
|
318 | context.receiverConfigured = m_coordinator ? m_coordinator->effectiveReceiver().isConfigured() |
| 205 |
5/7✓ Branch 8 → 9 taken 82 times.
✓ Branch 11 → 12 taken 82 times.
✓ Branch 11 → 13 taken 118 times.
✓ Branch 13 → 14 taken 118 times.
✓ Branch 13 → 15 taken 82 times.
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 66 not taken.
|
200 | : DavPushSettings::receiver().isConfigured(); |
| 206 |
1/1✓ Branch 15 → 16 taken 200 times.
|
200 | context.pushEnabled = DavPushSettings::enabled(); |
| 207 | 200 | context.intervalMinutes = | |
| 208 |
3/3✓ Branch 16 → 17 taken 125 times.
✓ Branch 16 → 18 taken 75 times.
✓ Branch 18 → 19 taken 75 times.
|
200 | qMax(1, status.intervalMinutes > 0 ? status.intervalMinutes : CalendarSyncCoordinator::configuredIntervalMinutes()); |
| 209 | // Data sync errors and the write outbox are the calendar's; address | ||
| 210 | // books report push state only (their sync status lives in contacts). | ||
| 211 |
6/6✓ Branch 22 → 23 taken 104 times.
✓ Branch 22 → 27 taken 96 times.
✓ Branch 25 → 26 taken 7 times.
✓ Branch 25 → 27 taken 97 times.
✓ Branch 28 → 29 taken 7 times.
✓ Branch 28 → 62 taken 193 times.
|
200 | if (m_calendar && status.kind != QLatin1String("addressbook")) { |
| 212 |
1/1✓ Branch 31 → 32 taken 7 times.
|
7 | const auto state = m_calendar->syncStatus()->state(status.accountId); |
| 213 |
2/2✓ Branch 34 → 35 taken 3 times.
✓ Branch 34 → 36 taken 4 times.
|
7 | if (state.state == QLatin1String("error")) context.accountSyncError = state.errorKind; |
| 214 |
5/5✓ Branch 38 → 39 taken 7 times.
✓ Branch 39 → 40 taken 7 times.
✓ Branch 40 → 41 taken 7 times.
✓ Branch 58 → 42 taken 4 times.
✓ Branch 58 → 59 taken 7 times.
|
11 | for (const auto &entry : m_calendar->store()->outboxEntries()) { |
| 215 |
5/6✓ Branch 44 → 45 taken 3 times.
✓ Branch 44 → 47 taken 1 time.
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 48 taken 3 times.
✓ Branch 49 → 50 taken 1 time.
✓ Branch 49 → 51 taken 3 times.
|
4 | if (entry.accountId != status.accountId || entry.calendarPath != status.path) continue; |
| 216 |
2/2✓ Branch 53 → 54 taken 2 times.
✓ Branch 53 → 55 taken 1 time.
|
3 | if (entry.state == QLatin1String("conflict")) ++context.conflicts; |
| 217 | 1 | else ++context.pendingWrites; | |
| 218 | 7 | } | |
| 219 | 7 | } | |
| 220 | 200 | return context; | |
| 221 | ✗ | } | |
| 222 | |||
| 223 | 984 | void QuickDavPush::refresh() { | |
| 224 |
4/4✓ Branch 3 → 4 taken 27 times.
✓ Branch 3 → 5 taken 957 times.
✓ Branch 4 → 10 taken 27 times.
✓ Branch 8 → 10 taken 939 times.
|
2925 | m_statuses = m_statusProvider ? m_statusProvider() |
| 225 |
2/2✓ Branch 6 → 7 taken 939 times.
✓ Branch 6 → 9 taken 18 times.
|
957 | : m_coordinator ? m_coordinator->statuses() |
| 226 | 984 | : QList<DavPushCollectionStatus>(); | |
| 227 | 984 | QList<DavPushRow> rows; | |
| 228 |
5/5✓ Branch 16 → 17 taken 171 times.
✓ Branch 17 → 18 taken 171 times.
✓ Branch 18 → 19 taken 171 times.
✓ Branch 23 → 15 taken 171 times.
✓ Branch 23 → 24 taken 984 times.
|
1155 | for (const auto &status : std::as_const(m_statuses)) rows.append(deriveRow(status, contextFor(status))); |
| 229 |
1/1✓ Branch 24 → 25 taken 984 times.
|
984 | m_model.setRows(rows); |
| 230 | 984 | ++m_revision; | |
| 231 |
1/1✓ Branch 25 → 26 taken 984 times.
|
984 | emit changed(); |
| 232 | 984 | } | |
| 233 | |||
| 234 | 997 | bool QuickDavPush::enabled() const { return DavPushSettings::enabled(); } | |
| 235 | |||
| 236 | 7 | void QuickDavPush::setEnabled(bool on) { | |
| 237 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 6 times.
|
7 | if (on == enabled()) return; |
| 238 | 6 | DavPushSettings::setEnabled(on); | |
| 239 |
8/8✓ Branch 6 → 7 taken 6 times.
✓ Branch 10 → 11 taken 6 times.
✓ Branch 11 → 12 taken 6 times.
✓ Branch 12 → 13 taken 3 times.
✓ Branch 12 → 14 taken 3 times.
✓ Branch 15 → 16 taken 6 times.
✓ Branch 19 → 8 taken 6 times.
✓ Branch 19 → 20 taken 6 times.
|
12 | qCInfo(lcQuickPush) << "Push" << (on ? "enabled" : "disabled"); |
| 240 |
2/2✓ Branch 21 → 22 taken 4 times.
✓ Branch 21 → 24 taken 2 times.
|
6 | if (m_coordinator) m_coordinator->reconfigure(); |
| 241 | 6 | refresh(); | |
| 242 | } | ||
| 243 | |||
| 244 |
1/1✓ Branch 2 → 3 taken 89 times.
|
89 | bool QuickDavPush::serviceConfigured() const { return DavPushSettings::receiver().isConfigured(); } |
| 245 |
1/1✓ Branch 2 → 3 taken 18 times.
|
18 | QString QuickDavPush::serviceServer() const { return DavPushSettings::receiver().server; } |
| 246 |
1/1✓ Branch 2 → 3 taken 19 times.
|
19 | bool QuickDavPush::serviceHasToken() const { return DavPushSettings::receiver().hasToken; } |
| 247 | 2 | QString QuickDavPush::publicServer() const { return DavPushSettings::kPublicNtfyServer; } | |
| 248 | |||
| 249 | 35 | bool QuickDavPush::systemServiceDetected() const { | |
| 250 |
6/6✓ Branch 3 → 4 taken 34 times.
✓ Branch 3 → 9 taken 1 time.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 33 times.
✓ Branch 11 → 12 taken 34 times.
✓ Branch 11 → 13 taken 1 time.
|
35 | return m_coordinator && !m_coordinator->systemDistributor().isEmpty(); |
| 251 | } | ||
| 252 | |||
| 253 | 36 | QString QuickDavPush::systemServiceName() const { | |
| 254 |
2/2✓ Branch 3 → 4 taken 35 times.
✓ Branch 3 → 6 taken 1 time.
|
36 | const QString name = m_coordinator ? m_coordinator->systemDistributor() : QString(); |
| 255 |
2/2✓ Branch 8 → 9 taken 34 times.
✓ Branch 8 → 10 taken 2 times.
|
36 | if (name.isEmpty()) return {}; |
| 256 |
3/3✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 15 taken 1 time.
✓ Branch 13 → 14 taken 1 time.
|
2 | if (name == QLatin1String("org.unifiedpush.Distributor.kde")) return tr("KDE (KUnifiedPush)"); |
| 257 |
1/1✓ Branch 18 → 19 taken 1 time.
|
1 | return name.mid(name.lastIndexOf(QLatin1Char('.')) + 1); |
| 258 | 36 | } | |
| 259 | |||
| 260 | 39 | bool QuickDavPush::useSystemService() const { return DavPushSettings::useSystemService(); } | |
| 261 | |||
| 262 | 5 | void QuickDavPush::setUseSystemService(bool use) { | |
| 263 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 5 times.
|
5 | if (use == useSystemService()) return; |
| 264 | 5 | DavPushSettings::setUseSystemService(use); | |
| 265 |
8/8✓ Branch 6 → 7 taken 5 times.
✓ Branch 10 → 11 taken 5 times.
✓ Branch 11 → 12 taken 5 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 3 times.
✓ Branch 15 → 16 taken 5 times.
✓ Branch 19 → 8 taken 5 times.
✓ Branch 19 → 20 taken 5 times.
|
10 | qCInfo(lcQuickPush) << "System push service" << (use ? "allowed" : "not used"); |
| 266 |
2/2✓ Branch 21 → 22 taken 3 times.
✓ Branch 21 → 24 taken 2 times.
|
5 | if (m_coordinator) m_coordinator->reconfigure(); |
| 267 | 5 | refresh(); | |
| 268 | } | ||
| 269 | |||
| 270 | 39 | bool QuickDavPush::systemServiceActive() const { | |
| 271 |
7/9✓ Branch 3 → 4 taken 35 times.
✓ Branch 3 → 9 taken 4 times.
✓ Branch 5 → 6 taken 35 times.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 34 times.
✓ Branch 11 → 12 taken 35 times.
✓ Branch 11 → 13 taken 4 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 17 not taken.
|
39 | return m_coordinator && m_coordinator->effectiveReceiver().provider == DavPushSettings::kSystemProvider; |
| 272 | } | ||
| 273 | |||
| 274 | 38 | QString QuickDavPush::serviceKind() const { | |
| 275 |
1/1✓ Branch 2 → 3 taken 38 times.
|
38 | const auto receiver = DavPushSettings::receiver(); |
| 276 |
2/2✓ Branch 4 → 5 taken 36 times.
✓ Branch 4 → 6 taken 2 times.
|
38 | if (!receiver.isConfigured()) return {}; |
| 277 |
6/6✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 10 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 16 taken 1 time.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 18 taken 1 time.
|
6 | return receiver.publicService ? QStringLiteral("public") : QStringLiteral("own"); |
| 278 | 38 | } | |
| 279 | |||
| 280 | 3 | void QuickDavPush::testService(const QString &kind, const QString &server, const QString &token) { | |
| 281 |
5/6✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 6 taken 2 times.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 2 times.
|
4 | if (m_test && m_test->running()) return; // a repeated click joins the running test |
| 282 |
2/3✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 2 times.
✓ Branch 14 → 15 taken 2 times.
|
2 | const QString origin = DavPushSettings::normaliseServer(kind == QLatin1String("public") ? publicServer() : server); |
| 283 |
2/2✓ Branch 17 → 18 taken 1 time.
✓ Branch 17 → 29 taken 1 time.
|
2 | if (origin.isEmpty()) { |
| 284 | 1 | m_testState = QStringLiteral("failed"); | |
| 285 |
1/1✓ Branch 24 → 25 taken 1 time.
|
1 | m_testMessage = tr("Enter the address of an HTTPS push service, e.g. https://ntfy.example.org."); |
| 286 |
1/1✓ Branch 27 → 28 taken 1 time.
|
1 | emit testChanged(); |
| 287 | 1 | return; | |
| 288 | } | ||
| 289 |
1/2✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 37 not taken.
|
1 | if (!m_test) { |
| 290 |
3/6✓ Branch 30 → 31 taken 1 time.
✓ Branch 31 → 32 taken 1 time.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 34 taken 1 time.
✗ Branch 62 → 63 not taken.
✗ Branch 62 → 64 not taken.
|
1 | m_test = new DavPushServiceTest(this); |
| 291 |
1/1✓ Branch 34 → 35 taken 1 time.
|
1 | connect(m_test, &DavPushServiceTest::finished, this, [this](DavPushServiceTest::Result result, const QString &) { |
| 292 |
3/6✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 1 time.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 1 time.
|
2 | m_testState = result == DavPushServiceTest::Result::Ok ? QStringLiteral("ok") : QStringLiteral("failed"); |
| 293 |
1/6✗ Branch 15 → 16 not taken.
✗ Branch 15 → 20 not taken.
✗ Branch 15 → 24 not taken.
✗ Branch 15 → 28 not taken.
✗ Branch 15 → 32 not taken.
✓ Branch 15 → 36 taken 1 time.
|
1 | switch (result) { |
| 294 | ✗ | case DavPushServiceTest::Result::Ok: | |
| 295 | ✗ | m_testMessage = tr("The push service works: a test message went through it and came back."); | |
| 296 | ✗ | break; | |
| 297 | ✗ | case DavPushServiceTest::Result::Tls: | |
| 298 | ✗ | m_testMessage = tr("The push service's certificate is not trusted."); | |
| 299 | ✗ | break; | |
| 300 | ✗ | case DavPushServiceTest::Result::Authentication: | |
| 301 | ✗ | m_testMessage = tr("The push service rejected the sign-in. Check the token."); | |
| 302 | ✗ | break; | |
| 303 | ✗ | case DavPushServiceTest::Result::NoDelivery: | |
| 304 | ✗ | m_testMessage = tr("The push service is reachable but did not deliver the test message."); | |
| 305 | ✗ | break; | |
| 306 | ✗ | case DavPushServiceTest::Result::InvalidUrl: | |
| 307 | ✗ | m_testMessage = tr("Enter the address of an HTTPS push service, e.g. https://ntfy.example.org."); | |
| 308 | ✗ | break; | |
| 309 | 1 | default: | |
| 310 |
1/1✓ Branch 36 → 37 taken 1 time.
|
1 | m_testMessage = tr("The push service cannot be reached."); |
| 311 | } | ||
| 312 | 1 | emit testChanged(); | |
| 313 | 1 | }); | |
| 314 | } | ||
| 315 | 1 | m_testState = QStringLiteral("testing"); | |
| 316 |
1/1✓ Branch 43 → 44 taken 1 time.
|
1 | m_testMessage = tr("Testing the push service…"); |
| 317 |
1/1✓ Branch 46 → 47 taken 1 time.
|
1 | emit testChanged(); |
| 318 |
2/2✓ Branch 47 → 48 taken 1 time.
✓ Branch 48 → 49 taken 1 time.
|
1 | m_test->start(origin, token.toUtf8()); |
| 319 | 2 | } | |
| 320 | |||
| 321 | 12 | void QuickDavPush::cancelTest() { | |
| 322 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 12 times.
|
12 | if (m_test) m_test->cancel(); |
| 323 | 12 | m_testState = QStringLiteral("idle"); | |
| 324 | 12 | m_testMessage.clear(); | |
| 325 | 12 | emit testChanged(); | |
| 326 | 12 | } | |
| 327 | |||
| 328 | 7 | QVariantMap QuickDavPush::saveService(const QString &kind, const QString &server, const QString &token) { | |
| 329 | 7 | DavPushSettings::Receiver receiver; | |
| 330 | 7 | receiver.provider = QStringLiteral("ntfy"); | |
| 331 | 7 | receiver.publicService = kind == QLatin1String("public"); | |
| 332 |
2/2✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 6 times.
|
7 | receiver.server = receiver.publicService ? publicServer() : server; |
| 333 |
6/17✓ Branch 16 → 17 taken 3 times.
✓ Branch 16 → 23 taken 4 times.
✓ Branch 17 → 18 taken 3 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 24 taken 3 times.
✗ Branch 19 → 20 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 7 times.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 7 times.
✗ Branch 127 → 128 not taken.
✗ Branch 127 → 129 not taken.
✗ Branch 131 → 132 not taken.
✗ Branch 131 → 133 not taken.
|
7 | receiver.hasToken = !token.isEmpty() || (serviceHasToken() && DavPushSettings::normaliseServer(receiver.server) == serviceServer()); |
| 334 | // S106-336: a token is saved only where it can be kept; the settings | ||
| 335 | // never claim a stored token whose write was skipped or failed. | ||
| 336 |
8/9✓ Branch 30 → 31 taken 4 times.
✓ Branch 30 → 37 taken 3 times.
✓ Branch 32 → 33 taken 3 times.
✓ Branch 32 → 36 taken 1 time.
✓ Branch 34 → 35 taken 3 times.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 3 times.
✓ Branch 38 → 39 taken 1 time.
✓ Branch 38 → 58 taken 6 times.
|
7 | if (!token.isEmpty() && !(m_coordinator && m_coordinator->isOpen())) |
| 337 | 2 | return {{QStringLiteral("ok"), false}, | |
| 338 |
3/5✓ Branch 46 → 47 taken 1 time.
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 52 taken 1 time.
✗ Branch 136 → 137 not taken.
✗ Branch 136 → 138 not taken.
|
5 | {QStringLiteral("error"), tr("The token cannot be stored right now: the push storage is not available.")}}; |
| 339 | 6 | QString error; | |
| 340 |
3/3✓ Branch 58 → 59 taken 6 times.
✓ Branch 59 → 60 taken 1 time.
✓ Branch 59 → 79 taken 5 times.
|
6 | if (!DavPushSettings::setReceiver(receiver, &error)) |
| 341 |
3/5✓ Branch 67 → 68 taken 1 time.
✓ Branch 71 → 72 taken 2 times.
✓ Branch 71 → 73 taken 1 time.
✗ Branch 162 → 163 not taken.
✗ Branch 162 → 164 not taken.
|
6 | return {{QStringLiteral("ok"), false}, {QStringLiteral("error"), tr("Enter the address of an HTTPS push service, e.g. https://ntfy.example.org.")}}; |
| 342 |
2/2✓ Branch 80 → 81 taken 3 times.
✓ Branch 80 → 93 taken 2 times.
|
5 | if (!token.isEmpty()) { |
| 343 |
1/1✓ Branch 81 → 82 taken 3 times.
|
3 | QPointer<QuickDavPush> self(this); |
| 344 |
3/5✓ Branch 85 → 86 taken 3 times.
✓ Branch 86 → 87 taken 3 times.
✓ Branch 87 → 88 taken 3 times.
✗ Branch 194 → 195 not taken.
✗ Branch 194 → 196 not taken.
|
3 | m_coordinator->storeProviderToken(token.toUtf8(), [self, receiver](bool ok) mutable { |
| 345 |
3/6✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 5 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
|
1 | if (ok || !self) return; |
| 346 | 1 | receiver.hasToken = false; | |
| 347 | 1 | QString ignored; | |
| 348 |
1/1✓ Branch 9 → 10 taken 1 time.
|
1 | DavPushSettings::setReceiver(receiver, &ignored); |
| 349 |
5/5✓ Branch 10 → 11 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 19 → 12 taken 1 time.
✓ Branch 19 → 20 taken 1 time.
|
2 | qCWarning(lcQuickPush) << "Push service token not stored; the service is kept without a token"; |
| 350 |
1/1✓ Branch 21 → 22 taken 1 time.
|
1 | self->refresh(); |
| 351 | 1 | }); | |
| 352 | 3 | } | |
| 353 |
8/8✓ Branch 93 → 94 taken 5 times.
✓ Branch 97 → 98 taken 5 times.
✓ Branch 98 → 99 taken 5 times.
✓ Branch 99 → 100 taken 1 time.
✓ Branch 99 → 101 taken 4 times.
✓ Branch 102 → 103 taken 5 times.
✓ Branch 106 → 95 taken 5 times.
✓ Branch 106 → 107 taken 5 times.
|
10 | qCInfo(lcQuickPush) << "Push service saved:" << (receiver.publicService ? "public" : "own"); |
| 354 |
3/3✓ Branch 108 → 109 taken 3 times.
✓ Branch 108 → 111 taken 2 times.
✓ Branch 110 → 111 taken 3 times.
|
5 | if (m_coordinator) m_coordinator->reconfigure(); |
| 355 |
1/1✓ Branch 111 → 112 taken 5 times.
|
5 | refresh(); |
| 356 |
2/4✓ Branch 118 → 119 taken 5 times.
✓ Branch 118 → 120 taken 5 times.
✗ Branch 208 → 209 not taken.
✗ Branch 208 → 210 not taken.
|
20 | return {{QStringLiteral("ok"), true}}; |
| 357 | 30 | } | |
| 358 | |||
| 359 | 2 | void QuickDavPush::removeService() { | |
| 360 | 2 | DavPushSettings::clearReceiver(); | |
| 361 |
2/2✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 7 taken 1 time.
|
2 | if (m_coordinator) m_coordinator->removeProviderToken(); // S106-337 |
| 362 |
2/2✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 11 taken 1 time.
|
2 | if (m_coordinator) m_coordinator->reconfigure(); |
| 363 | 2 | refresh(); | |
| 364 | 2 | } | |
| 365 | |||
| 366 | 3 | bool QuickDavPush::setAutomatic(const QString &key, bool automatic) { | |
| 367 |
1/1✓ Branch 2 → 3 taken 3 times.
|
3 | const auto status = statusOf(key); |
| 368 |
5/6✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 7 taken 1 time.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2 times.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 11 taken 2 times.
|
3 | if (!status || !m_coordinator) return false; |
| 369 |
3/3✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 1 time.
✓ Branch 17 → 18 taken 2 times.
|
2 | m_coordinator->setPolicy(status->accountId, status->path, |
| 370 | automatic ? DavPushPolicy::Automatic : DavPushPolicy::IntervalOnly); | ||
| 371 |
1/1✓ Branch 18 → 19 taken 2 times.
|
2 | refresh(); |
| 372 | 2 | return true; | |
| 373 | 3 | } | |
| 374 | |||
| 375 | 2 | void QuickDavPush::syncNow(const QString &key) { | |
| 376 |
6/7✓ Branch 2 → 3 taken 2 times.
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 8 taken 1 time.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 8 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 14 taken 1 time.
|
2 | if (const auto status = statusOf(key); status && m_coordinator) |
| 377 |
1/1✓ Branch 13 → 14 taken 1 time.
|
2 | m_coordinator->syncCollectionNow(status->accountId, status->path); |
| 378 | 2 | } | |
| 379 | |||
| 380 | 2 | void QuickDavPush::detectAgain(const QString &key) { | |
| 381 |
7/8✓ Branch 2 → 3 taken 2 times.
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 8 taken 1 time.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 8 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 13 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
|
2 | if (const auto status = statusOf(key); status && m_coordinator) m_coordinator->detectAgain(status->accountId); |
| 382 | 2 | } | |
| 383 | |||
| 384 | 2 | void QuickDavPush::reconnect(const QString &accountId) { | |
| 385 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 6 taken 1 time.
|
2 | if (m_coordinator) m_coordinator->reconnect(accountId); |
| 386 | 2 | } | |
| 387 | |||
| 388 | 2 | bool QuickDavPush::resetStatistics(const QString &key) { | |
| 389 |
1/1✓ Branch 2 → 3 taken 2 times.
|
2 | const auto status = statusOf(key); |
| 390 |
5/7✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 13 taken 1 time.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 13 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
|
2 | const bool ok = status && m_coordinator && m_coordinator->resetStatistics(status->accountId, status->path); |
| 391 |
1/1✓ Branch 14 → 15 taken 2 times.
|
2 | refresh(); |
| 392 | 2 | return ok; | |
| 393 | 2 | } | |
| 394 | |||
| 395 | 2 | bool QuickDavPush::copyDiagnostics() { | |
| 396 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1 time.
|
2 | if (!m_coordinator) return false; |
| 397 |
1/1✓ Branch 6 → 7 taken 1 time.
|
1 | const QString report = m_coordinator->diagnosticsReport(); |
| 398 |
4/5✓ Branch 8 → 9 taken 1 time.
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 11 → 12 taken 1 time.
|
1 | if (auto *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance())) app->clipboard()->setText(report); |
| 399 |
1/1✓ Branch 12 → 13 taken 1 time.
|
1 | emit diagnosticsReady(report); |
| 400 | 1 | return true; | |
| 401 | 1 | } | |
| 402 | |||
| 403 | 39 | std::optional<DavPushCollectionStatus> QuickDavPush::statusOf(const QString &key) const { | |
| 404 |
2/2✓ Branch 12 → 4 taken 44 times.
✓ Branch 12 → 13 taken 5 times.
|
49 | for (const auto &status : m_statuses) |
| 405 |
3/3✓ Branch 5 → 6 taken 44 times.
✓ Branch 8 → 9 taken 34 times.
✓ Branch 8 → 10 taken 10 times.
|
44 | if (calendarSelectionKey(status.accountId, status.path) == key) return status; |
| 406 | 5 | return std::nullopt; | |
| 407 | } | ||
| 408 | |||
| 409 | 2064 | QVariantMap QuickDavPush::statusFor(const QString &key, int) const { | |
| 410 |
2/2✓ Branch 50 → 5 taken 459 times.
✓ Branch 50 → 51 taken 2012 times.
|
2471 | for (const auto &row : m_model.rows()) { |
| 411 |
2/2✓ Branch 7 → 8 taken 407 times.
✓ Branch 7 → 9 taken 52 times.
|
459 | if (row.key != key) continue; |
| 412 | 104 | return {{QStringLiteral("stateKey"), row.stateKey}, | |
| 413 | 104 | {QStringLiteral("stateText"), row.stateText}, | |
| 414 | 104 | {QStringLiteral("severity"), row.severity}, | |
| 415 | 104 | {QStringLiteral("icon"), row.icon}, | |
| 416 |
4/6✓ Branch 28 → 29 taken 52 times.
✓ Branch 29 → 30 taken 52 times.
✓ Branch 33 → 34 taken 260 times.
✓ Branch 33 → 35 taken 52 times.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
|
416 | {QStringLiteral("accessibleName"), tr("%1: %2").arg(row.displayName, row.stateText)}}; |
| 417 | } | ||
| 418 | 2012 | return {}; | |
| 419 | 312 | } | |
| 420 | |||
| 421 | 1034 | QString QuickDavPush::summaryFor(const QVariantList &keys, int) const { | |
| 422 | 1034 | int total = 0; | |
| 423 | 1034 | int active = 0; | |
| 424 | 1034 | int problems = 0; | |
| 425 | 1034 | bool books = false; | |
| 426 |
2/2✓ Branch 31 → 5 taken 201 times.
✓ Branch 31 → 32 taken 1034 times.
|
1235 | for (const auto &row : m_model.rows()) { |
| 427 |
2/2✓ Branch 7 → 8 taken 147 times.
✓ Branch 7 → 9 taken 54 times.
|
201 | if (!keys.contains(row.key)) continue; |
| 428 | 54 | ++total; | |
| 429 |
3/4✓ Branch 9 → 10 taken 54 times.
✗ Branch 9 → 13 not taken.
✓ Branch 12 → 13 taken 7 times.
✓ Branch 12 → 14 taken 47 times.
|
54 | books = books || row.kind == QLatin1String("addressbook"); |
| 430 |
3/3✓ Branch 16 → 17 taken 54 times.
✓ Branch 17 → 18 taken 23 times.
✓ Branch 17 → 19 taken 31 times.
|
54 | if (row.stateKey.startsWith(QLatin1String("active"))) ++active; |
| 431 |
5/6✓ Branch 21 → 22 taken 47 times.
✓ Branch 21 → 25 taken 7 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 47 times.
✓ Branch 27 → 28 taken 7 times.
✓ Branch 27 → 29 taken 47 times.
|
54 | if (row.severity == QLatin1String("warning") || row.severity == QLatin1String("error")) ++problems; |
| 432 | } | ||
| 433 |
2/2✓ Branch 32 → 33 taken 1024 times.
✓ Branch 32 → 34 taken 10 times.
|
1034 | if (total == 0) return {}; |
| 434 |
1/3✓ Branch 35 → 36 taken 7 times.
✗ Branch 69 → 70 not taken.
✗ Branch 69 → 71 not taken.
|
14 | QString text = books ? tr("Push active for %1 of %n calendar(s) and address book(s)", "", total).arg(active) |
| 435 |
9/11✓ Branch 34 → 35 taken 7 times.
✓ Branch 34 → 38 taken 3 times.
✓ Branch 37 → 41 taken 7 times.
✓ Branch 38 → 39 taken 3 times.
✓ Branch 40 → 41 taken 3 times.
✓ Branch 41 → 42 taken 3 times.
✓ Branch 41 → 43 taken 7 times.
✓ Branch 43 → 44 taken 7 times.
✓ Branch 43 → 45 taken 3 times.
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 66 not taken.
|
17 | : tr("Push active for %1 of %n calendar(s)", "", total).arg(active); |
| 436 |
5/5✓ Branch 45 → 46 taken 7 times.
✓ Branch 45 → 57 taken 3 times.
✓ Branch 46 → 47 taken 7 times.
✓ Branch 50 → 51 taken 7 times.
✓ Branch 51 → 52 taken 7 times.
|
17 | if (problems > 0) text += QStringLiteral(" · ") + tr("%n with problems", "", problems); |
| 437 | 10 | return text; | |
| 438 | 10 | } | |
| 439 | |||
| 440 | 1010 | QString QuickDavPush::summaryText() const { | |
| 441 | 1010 | int active = 0; | |
| 442 | 1010 | bool interrupted = false; | |
| 443 | // The calendar/task sync line: calendars only. | ||
| 444 |
2/2✓ Branch 20 → 5 taken 134 times.
✓ Branch 20 → 21 taken 1010 times.
|
1144 | for (const auto &row : m_model.rows()) { |
| 445 |
2/2✓ Branch 8 → 9 taken 108 times.
✓ Branch 8 → 10 taken 26 times.
|
134 | if (row.kind != QLatin1String("calendar")) continue; |
| 446 |
3/3✓ Branch 11 → 12 taken 26 times.
✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 14 taken 17 times.
|
26 | if (row.stateKey.startsWith(QLatin1String("active"))) ++active; |
| 447 |
2/2✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 22 times.
|
26 | if (row.stateKey == QLatin1String("interrupted")) interrupted = true; |
| 448 | } | ||
| 449 |
2/2✓ Branch 21 → 22 taken 4 times.
✓ Branch 21 → 23 taken 1006 times.
|
1010 | if (interrupted) return tr("Push interrupted · interval sync active"); |
| 450 |
2/2✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 1005 times.
|
1006 | if (active > 0) return tr("Push connected for %n calendar(s)", "", active); |
| 451 | 1005 | return {}; | |
| 452 | } | ||
| 453 | |||
| 454 | 73 | QVariantList QuickDavPush::accounts() const { | |
| 455 | 73 | QVariantList result; | |
| 456 | 73 | QStringList seen; | |
| 457 |
2/2✓ Branch 75 → 5 taken 51 times.
✓ Branch 75 → 76 taken 73 times.
|
124 | for (const auto &row : m_model.rows()) { |
| 458 |
2/2✓ Branch 7 → 8 taken 43 times.
✓ Branch 7 → 9 taken 8 times.
|
51 | if (seen.contains(row.accountId)) continue; |
| 459 |
1/1✓ Branch 9 → 10 taken 8 times.
|
8 | seen << row.accountId; |
| 460 | 8 | QVariantList keys; | |
| 461 | 8 | QString problem; | |
| 462 |
2/2✓ Branch 34 → 13 taken 54 times.
✓ Branch 34 → 35 taken 8 times.
|
62 | for (const auto &other : m_model.rows()) { |
| 463 |
2/2✓ Branch 15 → 16 taken 3 times.
✓ Branch 15 → 17 taken 51 times.
|
54 | if (other.accountId != row.accountId) continue; |
| 464 |
1/1✓ Branch 18 → 19 taken 51 times.
|
51 | keys << other.key; |
| 465 |
7/8✓ Branch 21 → 22 taken 21 times.
✓ Branch 21 → 29 taken 30 times.
✓ Branch 24 → 25 taken 14 times.
✓ Branch 24 → 28 taken 7 times.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 14 times.
✓ Branch 30 → 31 taken 7 times.
✓ Branch 30 → 32 taken 44 times.
|
51 | if (problem.isEmpty() && (other.severity == QLatin1String("warning") || other.severity == QLatin1String("error"))) |
| 466 | 7 | problem = other.detailText; | |
| 467 | } | ||
| 468 |
1/1✓ Branch 54 → 55 taken 8 times.
|
24 | result.append(QVariantMap{{QStringLiteral("accountId"), row.accountId}, |
| 469 | 16 | {QStringLiteral("label"), row.accountLabel}, | |
| 470 |
1/1✓ Branch 46 → 47 taken 8 times.
|
16 | {QStringLiteral("summary"), summaryFor(keys)}, |
| 471 |
2/4✓ Branch 58 → 59 taken 32 times.
✓ Branch 58 → 60 taken 8 times.
✗ Branch 88 → 89 not taken.
✗ Branch 88 → 90 not taken.
|
48 | {QStringLiteral("problem"), problem}}); |
| 472 | 8 | } | |
| 473 | 73 | return result; | |
| 474 | 113 | } | |
| 475 | |||
| 476 | 64 | QString QuickDavPush::timeText(qint64 epochSeconds) const { | |
| 477 |
3/3✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 5 taken 60 times.
✓ Branch 3 → 4 taken 4 times.
|
64 | if (epochSeconds <= 0) return tr("Never"); |
| 478 |
1/1✓ Branch 5 → 6 taken 60 times.
|
60 | const QDateTime when = QDateTime::fromSecsSinceEpoch(epochSeconds); |
| 479 |
3/3✓ Branch 6 → 7 taken 60 times.
✓ Branch 7 → 8 taken 60 times.
✓ Branch 8 → 9 taken 60 times.
|
60 | const QDate today = QDateTime::fromSecsSinceEpoch(now()).date(); |
| 480 |
8/8✓ Branch 10 → 11 taken 60 times.
✓ Branch 12 → 13 taken 32 times.
✓ Branch 12 → 24 taken 28 times.
✓ Branch 13 → 14 taken 32 times.
✓ Branch 15 → 16 taken 32 times.
✓ Branch 16 → 17 taken 32 times.
✓ Branch 17 → 18 taken 32 times.
✓ Branch 18 → 19 taken 32 times.
|
92 | if (when.date() == today) return tr("Today, %1").arg(QLocale().toString(when.time(), QLocale::ShortFormat)); |
| 481 |
2/2✓ Branch 24 → 25 taken 28 times.
✓ Branch 25 → 26 taken 28 times.
|
28 | return QLocale().toString(when, QLocale::ShortFormat); |
| 482 | 60 | } | |
| 483 | |||
| 484 | 7 | QString QuickDavPush::relativeText(qint64 epochSeconds) const { | |
| 485 | 7 | const qint64 delta = epochSeconds - now(); | |
| 486 |
2/2✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 5 taken 3 times.
|
7 | if (delta <= 60) return tr("in less than a minute"); |
| 487 |
2/2✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 2 times.
|
3 | if (delta < 3600) return tr("in %n minute(s)", "", int(delta / 60)); |
| 488 |
3/3✓ Branch 7 → 8 taken 2 times.
✓ Branch 9 → 10 taken 2 times.
✓ Branch 10 → 11 taken 2 times.
|
4 | return tr("at %1").arg(timeText(epochSeconds)); |
| 489 | } | ||
| 490 | |||
| 491 | 29 | QVariantMap QuickDavPush::statisticsFor(const DavPushCollectionStatus &status) const { | |
| 492 | 29 | QVariantMap stats; | |
| 493 |
5/6✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 7 taken 27 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2 times.
✓ Branch 9 → 10 taken 27 times.
✓ Branch 9 → 11 taken 2 times.
|
29 | if (!m_coordinator || !m_coordinator->statistics()) return stats; |
| 494 | 2 | const auto *s = m_coordinator->statistics(); | |
| 495 |
1/1✓ Branch 13 → 14 taken 2 times.
|
2 | const QString scope = DavPushStatistics::collectionScope(status.accountId, status.path); |
| 496 |
1/1✓ Branch 14 → 15 taken 2 times.
|
2 | const QString account = DavPushStatistics::accountScope(status.accountId); |
| 497 |
1/1✓ Branch 15 → 16 taken 2 times.
|
2 | const qint64 dayAgo = now() - 24 * 3600; |
| 498 | 2 | QVariantList counters; | |
| 499 | 32 | const auto add = [&](const QString &label, const QString &scopeName, const char *name) { | |
| 500 |
1/1✓ Branch 22 → 23 taken 32 times.
|
96 | counters.append(QVariantMap{{QStringLiteral("label"), label}, |
| 501 |
2/2✓ Branch 10 → 11 taken 32 times.
✓ Branch 11 → 12 taken 32 times.
|
64 | {QStringLiteral("total"), s->counter(scopeName, QLatin1String(name))}, |
| 502 |
4/6✓ Branch 17 → 18 taken 32 times.
✓ Branch 18 → 19 taken 32 times.
✓ Branch 26 → 27 taken 96 times.
✓ Branch 26 → 28 taken 32 times.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 44 not taken.
|
160 | {QStringLiteral("day"), s->periodSum(scopeName, QLatin1String(name), dayAgo)}}); |
| 503 |
1/5✓ Branch 20 → 21 taken 32 times.
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 77 not taken.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 77 not taken.
|
160 | }; |
| 504 |
3/5✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 2 times.
✗ Branch 19 → 21 not taken.
✓ Branch 20 → 21 taken 2 times.
✓ Branch 21 → 22 taken 2 times.
|
2 | add(status.kind == QLatin1String("addressbook") ? tr("Changes received for this address book") |
| 505 | : tr("Changes received for this calendar"), | ||
| 506 | scope, "messages.mapped"); | ||
| 507 |
2/2✓ Branch 23 → 24 taken 2 times.
✓ Branch 24 → 25 taken 2 times.
|
2 | add(tr("Notices already applied (same sync token)"), scope, "messages.token-noop"); |
| 508 |
2/2✓ Branch 26 → 27 taken 2 times.
✓ Branch 27 → 28 taken 2 times.
|
2 | add(tr("Notices combined into one sync"), scope, "messages.coalesced"); |
| 509 |
2/2✓ Branch 29 → 30 taken 2 times.
✓ Branch 30 → 31 taken 2 times.
|
2 | add(tr("Syncs after a push notice"), scope, "syncs.push"); |
| 510 |
2/2✓ Branch 32 → 33 taken 2 times.
✓ Branch 33 → 34 taken 2 times.
|
2 | add(tr("Safety syncs (interval)"), scope, "syncs.poll"); |
| 511 |
2/2✓ Branch 35 → 36 taken 2 times.
✓ Branch 36 → 37 taken 2 times.
|
2 | add(tr("Catch-up syncs (recovery)"), scope, "syncs.recovery"); |
| 512 |
2/2✓ Branch 38 → 39 taken 2 times.
✓ Branch 39 → 40 taken 2 times.
|
2 | add(tr("Manual syncs"), scope, "syncs.manual"); |
| 513 |
2/2✓ Branch 41 → 42 taken 2 times.
✓ Branch 42 → 43 taken 2 times.
|
2 | add(tr("Failed syncs"), scope, "syncs.failed"); |
| 514 |
2/2✓ Branch 44 → 45 taken 2 times.
✓ Branch 45 → 46 taken 2 times.
|
2 | add(tr("Subscriptions registered"), scope, "subscription.registered"); |
| 515 |
2/2✓ Branch 47 → 48 taken 2 times.
✓ Branch 48 → 49 taken 2 times.
|
2 | add(tr("Subscriptions renewed"), scope, "subscription.renewed"); |
| 516 |
2/2✓ Branch 50 → 51 taken 2 times.
✓ Branch 51 → 52 taken 2 times.
|
2 | add(tr("Subscription errors"), scope, "subscription.failed"); |
| 517 |
2/2✓ Branch 53 → 54 taken 2 times.
✓ Branch 54 → 55 taken 2 times.
|
2 | add(tr("Messages received by the account (all calendars and address books)"), account, "messages.received"); |
| 518 |
2/2✓ Branch 56 → 57 taken 2 times.
✓ Branch 57 → 58 taken 2 times.
|
2 | add(tr("Messages discarded: unknown topic"), account, "messages.discarded.unknown-topic"); |
| 519 |
2/2✓ Branch 59 → 60 taken 2 times.
✓ Branch 60 → 61 taken 2 times.
|
2 | add(tr("Messages discarded: not decryptable"), account, "messages.discarded.decrypt"); |
| 520 |
2/2✓ Branch 62 → 63 taken 2 times.
✓ Branch 63 → 64 taken 2 times.
|
2 | add(tr("Push service reconnects"), account, "receiver.reconnects"); |
| 521 |
2/2✓ Branch 65 → 66 taken 2 times.
✓ Branch 66 → 67 taken 2 times.
|
2 | add(tr("Fallback periods"), account, "fallback.entered"); |
| 522 |
1/1✓ Branch 72 → 73 taken 2 times.
|
4 | stats.insert(QStringLiteral("counters"), counters); |
| 523 | 2 | QVariantList latencies; | |
| 524 |
1/1✓ Branch 79 → 80 taken 2 times.
|
14 | for (const auto &[kind, label] : {std::pair{QStringLiteral("push-start"), tr("Push → sync start")}, |
| 525 |
3/7✓ Branch 84 → 85 taken 2 times.
✓ Branch 143 → 95 taken 4 times.
✓ Branch 143 → 144 taken 2 times.
✗ Branch 310 → 311 not taken.
✗ Branch 310 → 314 not taken.
✗ Branch 312 → 313 not taken.
✗ Branch 312 → 314 not taken.
|
18 | std::pair{QStringLiteral("push-commit"), tr("Push → data stored")}}) { |
| 526 |
1/1✓ Branch 97 → 98 taken 4 times.
|
4 | const auto samples = s->latencies(scope, kind); |
| 527 |
1/1✓ Branch 99 → 100 taken 4 times.
|
4 | const auto [median, p95] = medianP95(samples); |
| 528 |
1/1✓ Branch 124 → 125 taken 4 times.
|
12 | latencies.append(QVariantMap{{QStringLiteral("label"), label}, |
| 529 | 8 | {QStringLiteral("text"), samples.isEmpty() | |
| 530 |
4/4✓ Branch 111 → 112 taken 2 times.
✓ Branch 111 → 113 taken 2 times.
✓ Branch 112 → 121 taken 2 times.
✓ Branch 120 → 121 taken 2 times.
|
10 | ? tr("not measured yet") |
| 531 |
11/19✓ Branch 113 → 114 taken 2 times.
✓ Branch 115 → 116 taken 2 times.
✓ Branch 117 → 118 taken 2 times.
✓ Branch 128 → 129 taken 8 times.
✓ Branch 128 → 130 taken 4 times.
✓ Branch 131 → 132 taken 2 times.
✓ Branch 131 → 133 taken 2 times.
✓ Branch 133 → 134 taken 2 times.
✓ Branch 133 → 135 taken 2 times.
✓ Branch 135 → 136 taken 2 times.
✓ Branch 135 → 137 taken 2 times.
✗ Branch 323 → 324 not taken.
✗ Branch 323 → 325 not taken.
✗ Branch 329 → 330 not taken.
✗ Branch 329 → 331 not taken.
✗ Branch 334 → 335 not taken.
✗ Branch 334 → 336 not taken.
✗ Branch 339 → 340 not taken.
✗ Branch 339 → 341 not taken.
|
18 | : tr("median %1 ms · p95 %2 ms · n = %3").arg(median).arg(p95).arg(samples.size())}}); |
| 532 | 10 | } | |
| 533 |
1/1✓ Branch 154 → 155 taken 2 times.
|
4 | stats.insert(QStringLiteral("latencies"), latencies); |
| 534 |
1/1✓ Branch 160 → 161 taken 2 times.
|
2 | const qint64 since = m_coordinator->store()->statisticsSince(scope); |
| 535 |
5/15✗ Branch 161 → 162 not taken.
✓ Branch 161 → 166 taken 2 times.
✗ Branch 162 → 163 not taken.
✗ Branch 164 → 165 not taken.
✗ Branch 165 → 167 not taken.
✓ Branch 166 → 167 taken 2 times.
✓ Branch 171 → 172 taken 2 times.
✗ Branch 176 → 177 not taken.
✓ Branch 176 → 178 taken 2 times.
✗ Branch 178 → 179 not taken.
✓ Branch 178 → 180 taken 2 times.
✗ Branch 394 → 395 not taken.
✗ Branch 394 → 396 not taken.
✗ Branch 399 → 400 not taken.
✗ Branch 399 → 401 not taken.
|
4 | stats.insert(QStringLiteral("sinceText"), since > 0 ? tr("Counting since %1").arg(timeText(since)) : tr("Nothing counted yet")); |
| 536 | 2 | QVariantList events; | |
| 537 |
5/6✓ Branch 182 → 183 taken 2 times.
✓ Branch 183 → 184 taken 2 times.
✓ Branch 185 → 186 taken 2 times.
✓ Branch 186 → 187 taken 2 times.
✗ Branch 219 → 188 not taken.
✓ Branch 219 → 220 taken 2 times.
|
2 | for (const auto &event : m_coordinator->store()->events(scope).mid(0, 10)) |
| 538 | ✗ | events.append(QVariantMap{{QStringLiteral("time"), timeText(event.at)}, {QStringLiteral("kind"), event.kind}, | |
| 539 |
0/4✗ Branch 208 → 209 not taken.
✗ Branch 208 → 210 not taken.
✗ Branch 413 → 414 not taken.
✗ Branch 413 → 415 not taken.
|
2 | {QStringLiteral("detail"), event.detail}}); |
| 540 |
1/1✓ Branch 225 → 226 taken 2 times.
|
4 | stats.insert(QStringLiteral("events"), events); |
| 541 | 2 | return stats; | |
| 542 | 14 | } | |
| 543 | |||
| 544 | 30 | QVariantMap QuickDavPush::details(const QString &key, int) const { | |
| 545 |
1/1✓ Branch 2 → 3 taken 30 times.
|
30 | const auto status = statusOf(key); |
| 546 |
2/2✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 29 times.
|
30 | if (!status) return {}; |
| 547 |
1/1✓ Branch 7 → 8 taken 29 times.
|
29 | const DavPushRowContext context = contextFor(*status); |
| 548 |
1/1✓ Branch 9 → 10 taken 29 times.
|
29 | const DavPushRow row = deriveRow(*status, context); |
| 549 | 29 | QString offer; | |
| 550 |
5/5✓ Branch 11 → 12 taken 18 times.
✓ Branch 11 → 16 taken 1 time.
✓ Branch 11 → 20 taken 1 time.
✓ Branch 11 → 24 taken 1 time.
✓ Branch 11 → 28 taken 8 times.
|
29 | switch (status->offer.capability) { |
| 551 |
1/1✓ Branch 12 → 13 taken 18 times.
|
18 | case DavPushCapability::Supported: offer = tr("Push supported"); break; |
| 552 |
1/1✓ Branch 16 → 17 taken 1 time.
|
1 | case DavPushCapability::Unsupported: offer = tr("No push offered"); break; |
| 553 |
1/1✓ Branch 20 → 21 taken 1 time.
|
1 | case DavPushCapability::Incompatible: offer = tr("Push offered, not usable"); break; |
| 554 |
1/1✓ Branch 24 → 25 taken 1 time.
|
1 | case DavPushCapability::ProbeError: offer = tr("Check failed; tried again later"); break; |
| 555 |
1/1✓ Branch 28 → 29 taken 8 times.
|
8 | default: offer = tr("Not checked yet"); break; |
| 556 | } | ||
| 557 | 29 | QString receiver; | |
| 558 |
6/6✓ Branch 33 → 34 taken 9 times.
✓ Branch 33 → 44 taken 1 time.
✓ Branch 33 → 48 taken 5 times.
✓ Branch 33 → 58 taken 1 time.
✓ Branch 33 → 62 taken 10 times.
✓ Branch 33 → 66 taken 3 times.
|
29 | switch (status->receiver) { |
| 559 | 9 | case DavPushReceiverState::Connected: | |
| 560 |
3/3✓ Branch 34 → 35 taken 9 times.
✓ Branch 37 → 38 taken 9 times.
✓ Branch 38 → 39 taken 9 times.
|
18 | receiver = tr("Connected (since %1)").arg(timeText(status->receiverConnectedSince / 1000)); |
| 561 | 9 | break; | |
| 562 |
1/1✓ Branch 44 → 45 taken 1 time.
|
1 | case DavPushReceiverState::Connecting: receiver = tr("Connecting…"); break; |
| 563 | 5 | case DavPushReceiverState::Backoff: | |
| 564 |
3/3✓ Branch 48 → 49 taken 5 times.
✓ Branch 51 → 52 taken 5 times.
✓ Branch 52 → 53 taken 5 times.
|
10 | receiver = tr("Interrupted; next attempt %1").arg(relativeText(status->receiverNextAttempt / 1000)); |
| 565 | 5 | break; | |
| 566 |
1/1✓ Branch 58 → 59 taken 1 time.
|
1 | case DavPushReceiverState::Failed: receiver = tr("Needs attention"); break; |
| 567 |
1/1✓ Branch 62 → 63 taken 10 times.
|
10 | case DavPushReceiverState::NotConfigured: receiver = tr("No push service chosen"); break; |
| 568 |
1/1✓ Branch 66 → 67 taken 3 times.
|
3 | default: receiver = tr("Not running"); break; |
| 569 | } | ||
| 570 | ✗ | QString registration; | |
| 571 |
5/5✓ Branch 71 → 72 taken 12 times.
✓ Branch 71 → 82 taken 1 time.
✓ Branch 71 → 86 taken 1 time.
✓ Branch 71 → 90 taken 2 times.
✓ Branch 71 → 100 taken 13 times.
|
29 | switch (status->registration) { |
| 572 |
3/3✓ Branch 72 → 73 taken 12 times.
✓ Branch 75 → 76 taken 12 times.
✓ Branch 76 → 77 taken 12 times.
|
24 | case DavPushRegistrationState::Active: registration = tr("Subscribed until %1").arg(timeText(status->expiresAt)); break; |
| 573 |
1/1✓ Branch 82 → 83 taken 1 time.
|
1 | case DavPushRegistrationState::Registering: registration = tr("Subscribing…"); break; |
| 574 |
1/1✓ Branch 86 → 87 taken 1 time.
|
1 | case DavPushRegistrationState::Removing: registration = tr("Removing the subscription…"); break; |
| 575 | 2 | case DavPushRegistrationState::Failed: | |
| 576 |
3/3✓ Branch 90 → 91 taken 2 times.
✓ Branch 93 → 94 taken 2 times.
✓ Branch 94 → 95 taken 2 times.
|
4 | registration = tr("Failed; next attempt %1").arg(relativeText(status->nextRetryAt)); |
| 577 | 2 | break; | |
| 578 |
1/1✓ Branch 100 → 101 taken 13 times.
|
13 | default: registration = tr("Not subscribed"); break; |
| 579 | } | ||
| 580 | 29 | qint64 nextPollMs = -1; | |
| 581 |
7/8✓ Branch 107 → 108 taken 27 times.
✓ Branch 107 → 114 taken 2 times.
✓ Branch 109 → 110 taken 2 times.
✓ Branch 109 → 114 taken 25 times.
✓ Branch 112 → 113 taken 2 times.
✗ Branch 112 → 114 not taken.
✓ Branch 115 → 116 taken 2 times.
✓ Branch 115 → 120 taken 27 times.
|
29 | if (status->kind != QLatin1String("addressbook") && m_calendar && m_calendar->scheduler()) |
| 582 |
1/1✓ Branch 118 → 119 taken 2 times.
|
2 | nextPollMs = m_calendar->scheduler()->msUntilNextPoll(); |
| 583 | 58 | return {{QStringLiteral("key"), key}, | |
| 584 | 58 | {QStringLiteral("kind"), row.kind}, | |
| 585 | 58 | {QStringLiteral("accountId"), status->accountId}, | |
| 586 | 58 | {QStringLiteral("title"), status->displayName}, | |
| 587 | 58 | {QStringLiteral("accountLabel"), status->accountLabel}, | |
| 588 | 58 | {QStringLiteral("automatic"), status->policy == DavPushPolicy::Automatic}, | |
| 589 |
4/4✓ Branch 152 → 153 taken 23 times.
✓ Branch 152 → 154 taken 6 times.
✓ Branch 153 → 155 taken 23 times.
✓ Branch 154 → 155 taken 6 times.
|
58 | {QStringLiteral("modeText"), status->policy == DavPushPolicy::Automatic ? tr("Automatic") : tr("Interval only")}, |
| 590 | 58 | {QStringLiteral("offerText"), offer}, | |
| 591 | 58 | {QStringLiteral("receiverText"), receiver}, | |
| 592 | 58 | {QStringLiteral("registrationText"), registration}, | |
| 593 |
4/4✓ Branch 172 → 173 taken 20 times.
✓ Branch 172 → 175 taken 9 times.
✓ Branch 174 → 176 taken 20 times.
✓ Branch 175 → 176 taken 9 times.
|
58 | {QStringLiteral("lastMessageText"), status->lastPushAt > 0 ? timeText(status->lastPushAt) : tr("No change received yet")}, |
| 594 |
10/14✓ Branch 181 → 182 taken 21 times.
✓ Branch 181 → 187 taken 8 times.
✓ Branch 182 → 183 taken 21 times.
✓ Branch 185 → 186 taken 21 times.
✓ Branch 186 → 188 taken 21 times.
✓ Branch 187 → 188 taken 8 times.
✓ Branch 297 → 298 taken 21 times.
✓ Branch 297 → 299 taken 8 times.
✓ Branch 299 → 300 taken 21 times.
✓ Branch 299 → 301 taken 8 times.
✗ Branch 470 → 471 not taken.
✗ Branch 470 → 472 not taken.
✗ Branch 475 → 476 not taken.
✗ Branch 475 → 477 not taken.
|
58 | {QStringLiteral("dataText"), status->lastSyncAt > 0 ? tr("Updated successfully at %1").arg(timeText(status->lastSyncAt)) |
| 595 | : tr("Not synchronized yet")}, | ||
| 596 |
1/3✓ Branch 192 → 193 taken 29 times.
✗ Branch 192 → 194 not taken.
✗ Branch 198 → 199 not taken.
|
58 | {QStringLiteral("nextText"), nextPollMs < 0 ? QString() |
| 597 |
2/11✗ Branch 194 → 195 not taken.
✗ Branch 196 → 197 not taken.
✗ Branch 197 → 198 not taken.
✗ Branch 290 → 291 not taken.
✓ Branch 290 → 292 taken 29 times.
✗ Branch 292 → 293 not taken.
✓ Branch 292 → 294 taken 29 times.
✗ Branch 452 → 453 not taken.
✗ Branch 452 → 454 not taken.
✗ Branch 457 → 458 not taken.
✗ Branch 457 → 459 not taken.
|
29 | : tr("Safety sync %1").arg(relativeText(now() + nextPollMs / 1000))}, |
| 598 | 58 | {QStringLiteral("stateKey"), row.stateKey}, | |
| 599 | 58 | {QStringLiteral("stateText"), row.stateText}, | |
| 600 | 58 | {QStringLiteral("detailText"), row.detailText}, | |
| 601 | 58 | {QStringLiteral("severity"), row.severity}, | |
| 602 | 87 | {QStringLiteral("errorText"), status->registrationError.isEmpty() ? status->receiverDetail : status->registrationError}, | |
| 603 | 58 | {QStringLiteral("needsCredentials"), credentialsKind(context.accountSyncError)}, | |
| 604 |
2/2✓ Branch 237 → 238 taken 23 times.
✓ Branch 237 → 244 taken 6 times.
|
87 | {QStringLiteral("canReconnect"), context.receiverConfigured && status->policy == DavPushPolicy::Automatic && |
| 605 |
4/6✓ Branch 235 → 236 taken 29 times.
✗ Branch 235 → 244 not taken.
✓ Branch 239 → 240 taken 17 times.
✓ Branch 239 → 244 taken 6 times.
✓ Branch 242 → 243 taken 17 times.
✗ Branch 242 → 244 not taken.
|
75 | status->offer.capability == DavPushCapability::Supported && |
| 606 | 17 | status->pauseReason.isEmpty()}, | |
| 607 | 58 | {QStringLiteral("canSync"), status->pauseReason != QLatin1String("offline")}, | |
| 608 | 58 | {QStringLiteral("syncing"), status->syncRunning}, | |
| 609 |
3/5✓ Branch 262 → 263 taken 29 times.
✓ Branch 266 → 267 taken 667 times.
✓ Branch 266 → 268 taken 29 times.
✗ Branch 380 → 381 not taken.
✗ Branch 380 → 382 not taken.
|
754 | {QStringLiteral("statistics"), statisticsFor(*status)}}; |
| 610 | 755 | } | |
| 611 |