presentation/DavCollectionDiscovery.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "DavCollectionDiscovery.h" | ||
| 2 | #include "service/CalDavClient.h" | ||
| 3 | #include "service/CardDavClient.h" | ||
| 4 | #include "util/SecureUtil.h" | ||
| 5 | #include <QJsonArray> | ||
| 6 | #include <QJsonDocument> | ||
| 7 | #include <QJsonObject> | ||
| 8 | #include <QSet> | ||
| 9 | #include <QSettings> | ||
| 10 | #include <QTimer> | ||
| 11 | #include <QUrl> | ||
| 12 | |||
| 13 | 1622 | DavCollectionDiscovery::DavCollectionDiscovery(QObject *parent) : QAbstractListModel(parent) { | |
| 14 | 816 | m_resolver = [](QObject *owner, const Account &account, DavCredentials::PasswordCallback callback) { | |
| 15 |
1/1✓ Branch 5 → 6 taken 5 times.
|
5 | DavCredentials::readPasswordAsync(owner, account.id, account.serverUrl, account.username, std::move(callback)); |
| 16 | 816 | }; | |
| 17 | 811 | m_calendarFactory = [](const Account &a, const QByteArray &password) { | |
| 18 | ✗ | return new CalDavClient(a.serverUrl, a.username, QString::fromUtf8(password)); | |
| 19 | 811 | }; | |
| 20 | 811 | m_bookFactory = [](const Account &a, const QByteArray &password) { | |
| 21 | ✗ | return new CardDavClient(a.serverUrl, a.username, QString::fromUtf8(password)); | |
| 22 | 811 | }; | |
| 23 |
1/1✓ Branch 24 → 25 taken 811 times.
|
811 | connect(this, &QAbstractItemModel::modelReset, this, &DavCollectionDiscovery::countChanged); |
| 24 |
1/1✓ Branch 26 → 27 taken 811 times.
|
811 | connect(this, &QAbstractItemModel::rowsInserted, this, &DavCollectionDiscovery::countChanged); |
| 25 |
1/1✓ Branch 28 → 29 taken 811 times.
|
811 | connect(this, &QAbstractItemModel::rowsRemoved, this, &DavCollectionDiscovery::countChanged); |
| 26 | 811 | } | |
| 27 |
2/2✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 810 times.
|
811 | DavCollectionDiscovery::~DavCollectionDiscovery() { ++m_generation; delete m_request.data(); } |
| 28 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 246 times.
|
246 | int DavCollectionDiscovery::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : m_rows.size(); } |
| 29 | 18 | QHash<int, QByteArray> DavCollectionDiscovery::roleNames() const { | |
| 30 | ✗ | return {{Name, "collectionName"}, {Path, "collectionPath"}, {Kind, "collectionKind"}, | |
| 31 | ✗ | {Selected, "collectionSelected"}, {Available, "collectionAvailable"}, {Color, "collectionColor"}, | |
| 32 | ✗ | {Content, "collectionContent"}, {ReadOnly, "collectionReadOnly"}, {Push, "collectionPush"}, | |
| 33 |
2/4✓ Branch 15 → 16 taken 198 times.
✓ Branch 15 → 17 taken 18 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
|
216 | {Reason, "collectionReason"}, {Key, "collectionKey"}}; |
| 34 | 18 | } | |
| 35 | 129 | QVariant DavCollectionDiscovery::data(const QModelIndex &index, int role) const { | |
| 36 |
4/8✓ Branch 3 → 4 taken 129 times.
✗ Branch 3 → 9 not taken.
✓ Branch 5 → 6 taken 129 times.
✗ Branch 5 → 9 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 129 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 129 times.
|
129 | if (!index.isValid() || index.row() < 0 || index.row() >= m_rows.size()) return {}; |
| 37 | 129 | const auto &row = m_rows.at(index.row()); | |
| 38 |
10/12✓ Branch 15 → 16 taken 12 times.
✓ Branch 15 → 17 taken 15 times.
✗ Branch 15 → 18 not taken.
✓ Branch 15 → 32 taken 15 times.
✓ Branch 15 → 33 taken 13 times.
✓ Branch 15 → 34 taken 12 times.
✓ Branch 15 → 35 taken 12 times.
✓ Branch 15 → 39 taken 12 times.
✓ Branch 15 → 40 taken 12 times.
✓ Branch 15 → 41 taken 13 times.
✓ Branch 15 → 45 taken 13 times.
✗ Branch 15 → 49 not taken.
|
129 | switch (role) { |
| 39 | 12 | case Name: return row.name; | |
| 40 | 15 | case Path: return row.path; | |
| 41 | ✗ | case Kind: return row.calendar ? QStringLiteral("calendar") : QStringLiteral("book"); | |
| 42 | 15 | case Selected: return row.selected; | |
| 43 | 13 | case Available: return row.available; | |
| 44 | 12 | case Color: return row.color; | |
| 45 |
1/1✓ Branch 35 → 36 taken 12 times.
|
12 | case Content: return contentKind(row); |
| 46 | 12 | case ReadOnly: return row.readOnly; | |
| 47 | 12 | case Push: return row.push; | |
| 48 |
1/1✓ Branch 41 → 42 taken 13 times.
|
13 | case Reason: return defaultOffReason(row.path, row.calendar); |
| 49 |
1/1✓ Branch 45 → 46 taken 13 times.
|
13 | case Key: return collectionKey(row.path); |
| 50 | ✗ | default: return {}; | |
| 51 | } | ||
| 52 | } | ||
| 53 | 51 | void DavCollectionDiscovery::stopRequest() { | |
| 54 | 51 | ++m_generation; | |
| 55 |
2/2✓ Branch 3 → 4 taken 24 times.
✓ Branch 3 → 6 taken 27 times.
|
51 | if (m_request) m_request->deleteLater(); |
| 56 | 51 | m_request = nullptr; | |
| 57 | 51 | m_busy = false; | |
| 58 | 51 | } | |
| 59 | 27 | void DavCollectionDiscovery::cancel() { | |
| 60 | 27 | stopRequest(); | |
| 61 | 27 | beginResetModel(); m_rows.clear(); endResetModel(); | |
| 62 | 27 | m_dirty = false; m_calendarsOk = false; m_booksOk = false; | |
| 63 | 54 | m_error.clear(); m_state = QStringLiteral("cancelled"); | |
| 64 | 27 | emit stateChanged(); | |
| 65 | 27 | } | |
| 66 | 7 | void DavCollectionDiscovery::fail(const QString &error) { | |
| 67 | 7 | stopRequest(); | |
| 68 | 14 | m_error = error; m_state = QStringLiteral("error"); | |
| 69 | 7 | m_dirty = false; m_calendarsOk = false; m_booksOk = false; | |
| 70 | 7 | emit stateChanged(); | |
| 71 | 7 | } | |
| 72 | 74 | bool DavCollectionDiscovery::currentConfiguration() const { | |
| 73 | 74 | int found = 0; | |
| 74 |
5/5✓ Branch 2 → 3 taken 74 times.
✓ Branch 3 → 4 taken 74 times.
✓ Branch 4 → 5 taken 74 times.
✓ Branch 15 → 6 taken 75 times.
✓ Branch 15 → 16 taken 73 times.
|
148 | for (const auto &account : DavAccountSettings::accounts()) |
| 75 |
7/7✓ Branch 8 → 9 taken 68 times.
✓ Branch 8 → 13 taken 7 times.
✓ Branch 9 → 10 taken 68 times.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 67 times.
✓ Branch 18 → 19 taken 73 times.
✓ Branch 18 → 21 taken 1 time.
|
148 | if (account.id == m_account.id) { if (account != m_account) return false; ++found; } |
| 76 |
2/2✓ Branch 20 → 22 taken 6 times.
✓ Branch 20 → 23 taken 67 times.
|
73 | if (found != 1) return false; |
| 77 | 67 | auto current = DavAccountSettings::CalendarConfig{m_account.id, {}, {}}; | |
| 78 | 67 | found = 0; | |
| 79 |
5/5✓ Branch 24 → 25 taken 67 times.
✓ Branch 25 → 26 taken 67 times.
✓ Branch 26 → 27 taken 67 times.
✓ Branch 35 → 28 taken 13 times.
✓ Branch 35 → 36 taken 67 times.
|
80 | for (const auto &config : DavAccountSettings::calendarConfigs()) |
| 80 |
1/2✓ Branch 30 → 31 taken 13 times.
✗ Branch 30 → 33 not taken.
|
80 | if (config.accountId == m_account.id) { current = config; ++found; } |
| 81 |
3/5✓ Branch 37 → 38 taken 67 times.
✗ Branch 37 → 41 not taken.
✓ Branch 38 → 39 taken 67 times.
✓ Branch 39 → 40 taken 67 times.
✗ Branch 39 → 41 not taken.
|
67 | return found <= 1 && current == m_calendarConfig; |
| 82 | 67 | } | |
| 83 | 17 | void DavCollectionDiscovery::invalidateConfiguration() { | |
| 84 |
6/6✓ Branch 3 → 4 taken 8 times.
✓ Branch 3 → 7 taken 9 times.
✓ Branch 5 → 6 taken 5 times.
✓ Branch 5 → 7 taken 3 times.
✓ Branch 8 → 9 taken 5 times.
✓ Branch 8 → 13 taken 12 times.
|
17 | if (!m_account.id.isEmpty() && !currentConfiguration()) |
| 85 |
2/2✓ Branch 9 → 10 taken 5 times.
✓ Branch 10 → 11 taken 5 times.
|
5 | fail(tr("The account settings changed. Discover its collections again.")); |
| 86 | 17 | } | |
| 87 | 179 | QString DavCollectionDiscovery::collectionKey(const QString &path) const { | |
| 88 | 179 | return keyFor(m_account.serverUrl, path); | |
| 89 | } | ||
| 90 | 1297 | QString DavCollectionDiscovery::keyFor(const QString &serverUrl, const QString &path) { | |
| 91 |
3/6✓ Branch 3 → 4 taken 1297 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1297 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 1297 times.
|
1297 | if (path.isEmpty() || path.size() > 4096) return {}; |
| 92 |
5/8✓ Branch 13 → 14 taken 16724 times.
✗ Branch 13 → 16 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 16724 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 16724 times.
✓ Branch 21 → 12 taken 16724 times.
✓ Branch 21 → 22 taken 1297 times.
|
18021 | for (const auto ch : path) if (ch.isNull() || ch.category() == QChar::Other_Control) return {}; |
| 93 |
2/2✓ Branch 24 → 26 taken 1297 times.
✓ Branch 26 → 27 taken 1297 times.
|
1297 | QUrl base(serverUrl + QLatin1Char('/')); |
| 94 |
1/1✓ Branch 28 → 29 taken 1297 times.
|
1297 | const QUrl candidate(path, QUrl::StrictMode); |
| 95 |
4/4✓ Branch 29 → 30 taken 1297 times.
✓ Branch 30 → 31 taken 1296 times.
✓ Branch 30 → 32 taken 1 time.
✓ Branch 31 → 33 taken 1296 times.
|
1297 | const QUrl resolved = candidate.isRelative() ? base.resolved(candidate) : candidate; |
| 96 |
6/9✓ Branch 33 → 34 taken 1297 times.
✓ Branch 34 → 35 taken 1297 times.
✗ Branch 34 → 45 not taken.
✓ Branch 35 → 36 taken 1297 times.
✓ Branch 36 → 37 taken 1297 times.
✗ Branch 36 → 45 not taken.
✓ Branch 37 → 38 taken 1297 times.
✓ Branch 38 → 39 taken 1297 times.
✗ Branch 38 → 45 not taken.
|
2594 | if (!resolved.isValid() || resolved.hasQuery() || resolved.hasFragment() || |
| 97 |
10/19✓ Branch 39 → 40 taken 1297 times.
✓ Branch 41 → 42 taken 1297 times.
✓ Branch 42 → 43 taken 1297 times.
✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 46 taken 1296 times.
✓ Branch 47 → 48 taken 1297 times.
✗ Branch 47 → 49 not taken.
✓ Branch 49 → 50 taken 1297 times.
✗ Branch 49 → 51 not taken.
✓ Branch 51 → 52 taken 1297 times.
✗ Branch 51 → 53 not taken.
✓ Branch 53 → 54 taken 1 time.
✓ Branch 53 → 55 taken 1296 times.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 70 not taken.
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 74 not taken.
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 79 not taken.
|
2594 | DavCredentials::canonicalOrigin(resolved.toString()) != DavCredentials::canonicalOrigin(serverUrl)) return {}; |
| 98 |
1/1✓ Branch 56 → 57 taken 1296 times.
|
1296 | return resolved.toString(QUrl::FullyEncoded); |
| 99 | 1297 | } | |
| 100 | 26 | bool DavCollectionDiscovery::discover(const QString &id) { | |
| 101 |
1/1✓ Branch 2 → 3 taken 26 times.
|
26 | QPointer<DavCollectionDiscovery> guard(this); |
| 102 | 26 | const auto nextGeneration = m_generation + 1; | |
| 103 |
1/1✓ Branch 3 → 4 taken 26 times.
|
26 | cancel(); |
| 104 |
3/6✓ Branch 5 → 6 taken 26 times.
✗ Branch 5 → 7 not taken.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 26 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 26 times.
|
26 | if (!guard || m_generation != nextGeneration) return false; |
| 105 | 26 | m_account = {}; | |
| 106 | 26 | int found = 0; | |
| 107 |
5/5✓ Branch 13 → 14 taken 26 times.
✓ Branch 14 → 15 taken 26 times.
✓ Branch 15 → 16 taken 26 times.
✓ Branch 24 → 17 taken 27 times.
✓ Branch 24 → 25 taken 26 times.
|
53 | for (const auto &account : DavAccountSettings::accounts()) |
| 108 |
2/2✓ Branch 19 → 20 taken 26 times.
✓ Branch 19 → 22 taken 1 time.
|
53 | if (account.id == id) { m_account = account; ++found; } |
| 109 | 26 | m_calendarConfig = {id, {}, {}}; | |
| 110 | 26 | int configs = 0; | |
| 111 |
5/5✓ Branch 29 → 30 taken 26 times.
✓ Branch 30 → 31 taken 26 times.
✓ Branch 31 → 32 taken 26 times.
✓ Branch 40 → 33 taken 4 times.
✓ Branch 40 → 41 taken 26 times.
|
30 | for (const auto &config : DavAccountSettings::calendarConfigs()) |
| 112 |
1/2✓ Branch 35 → 36 taken 4 times.
✗ Branch 35 → 38 not taken.
|
30 | if (config.accountId == id) { m_calendarConfig = config; ++configs; } |
| 113 |
2/6✓ Branch 42 → 43 taken 26 times.
✗ Branch 42 → 44 not taken.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 48 taken 26 times.
✗ Branch 44 → 45 not taken.
✗ Branch 45 → 46 not taken.
|
26 | if (found != 1 || configs > 1) { fail(tr("This DAV account is no longer available.")); return false; } |
| 114 |
4/4✓ Branch 48 → 49 taken 1 time.
✓ Branch 48 → 53 taken 25 times.
✓ Branch 49 → 50 taken 1 time.
✓ Branch 50 → 51 taken 1 time.
|
26 | if (m_account.requiresLocalAuthorization) { fail(tr("Authorize this account locally before discovering collections.")); return false; } |
| 115 |
2/2✓ Branch 53 → 54 taken 25 times.
✓ Branch 54 → 55 taken 25 times.
|
25 | m_calendars.clear(); m_books.clear(); m_calendarError.clear(); m_bookError.clear(); |
| 116 | 25 | m_calendarsDone = m_booksDone = false; | |
| 117 |
4/7✓ Branch 57 → 58 taken 25 times.
✓ Branch 58 → 59 taken 25 times.
✓ Branch 59 → 60 taken 25 times.
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 62 taken 25 times.
✗ Branch 102 → 103 not taken.
✗ Branch 102 → 104 not taken.
|
25 | m_request = new QObject(this); |
| 118 | 25 | const auto generation = ++m_generation; | |
| 119 | 50 | m_busy = true; m_state = QStringLiteral("credentials"); | |
| 120 |
1/3✓ Branch 70 → 71 taken 25 times.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
|
25 | QTimer::singleShot(30000, m_request, [guard, generation] { |
| 121 | ✗ | if (guard && guard->m_generation == generation) guard->fail(tr("Collection discovery timed out. Try again.")); | |
| 122 | ✗ | }); | |
| 123 |
1/1✓ Branch 72 → 73 taken 25 times.
|
25 | emit stateChanged(); |
| 124 |
3/6✓ Branch 74 → 75 taken 25 times.
✗ Branch 74 → 76 not taken.
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 77 taken 25 times.
✗ Branch 78 → 79 not taken.
✓ Branch 78 → 80 taken 25 times.
|
25 | if (!guard || generation != m_generation) return false; |
| 125 |
2/4✓ Branch 81 → 82 taken 25 times.
✓ Branch 83 → 84 taken 25 times.
✗ Branch 115 → 116 not taken.
✗ Branch 115 → 117 not taken.
|
25 | m_resolver(m_request, m_account, [guard, generation](QByteArray password, QString error) { |
| 126 |
6/7✓ Branch 3 → 4 taken 20 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 18 times.
✓ Branch 5 → 7 taken 2 times.
✓ Branch 8 → 9 taken 18 times.
✓ Branch 8 → 15 taken 2 times.
✓ Branch 12 → 13 taken 18 times.
|
20 | if (guard && guard->m_generation == generation) guard->beginNetwork(generation, std::move(password), error); |
| 127 | 20 | }); | |
| 128 | 25 | return true; | |
| 129 | 52 | } | |
| 130 | 18 | void DavCollectionDiscovery::beginNetwork(quint64 generation, QByteArray password, const QString &error) { | |
| 131 |
5/5✓ Branch 2 → 3 taken 18 times.
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 8 taken 17 times.
✓ Branch 4 → 5 taken 1 time.
✓ Branch 5 → 6 taken 1 time.
|
18 | if (!currentConfiguration()) { fail(tr("The account settings changed. Discover its collections again.")); return; } |
| 132 |
1/4✗ Branch 9 → 10 not taken.
✓ Branch 9 → 26 taken 17 times.
✗ Branch 17 → 18 not taken.
✗ Branch 19 → 20 not taken.
|
17 | if (password.isEmpty()) { fail(tr("No password is stored for this account. Enter it with Edit, save, then discover again.") + |
| 133 | ✗ | (error.isEmpty() ? QString{} : QLatin1Char('\n') + error.left(1024))); return; } | |
| 134 |
1/1✓ Branch 26 → 27 taken 17 times.
|
17 | QPointer<DavCollectionDiscovery> guard(this); |
| 135 | 17 | m_state = QStringLiteral("discovering"); | |
| 136 |
1/1✓ Branch 33 → 34 taken 17 times.
|
17 | auto *calendar = m_calendarFactory(m_account, password); |
| 137 |
1/1✓ Branch 34 → 35 taken 17 times.
|
17 | auto *books = m_bookFactory(m_account, password); |
| 138 |
1/1✓ Branch 35 → 36 taken 17 times.
|
17 | SecureUtil::zeroMemory(password); |
| 139 |
2/10✓ Branch 36 → 37 taken 17 times.
✗ Branch 36 → 38 not taken.
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 46 taken 17 times.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 42 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 43 → 44 not taken.
|
17 | if (!calendar || !books) { delete calendar; delete books; fail(tr("Collection discovery could not start.")); return; } |
| 140 |
2/2✓ Branch 47 → 48 taken 17 times.
✓ Branch 49 → 50 taken 17 times.
|
17 | calendar->setParent(m_request); books->setParent(m_request); |
| 141 |
1/3✓ Branch 52 → 53 taken 17 times.
✗ Branch 118 → 119 not taken.
✗ Branch 118 → 120 not taken.
|
17 | connect(calendar, &CalDavClient::calendarsDiscovered, m_request, [guard, generation](const QList<CalendarInfo> &items) { |
| 142 |
3/6✓ Branch 3 → 4 taken 17 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 17 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 17 times.
|
17 | if (!guard || guard->m_generation != generation) return; |
| 143 | 17 | QList<Item> values; | |
| 144 |
1/2✓ Branch 11 → 12 taken 17 times.
✗ Branch 11 → 25 not taken.
|
17 | if (items.size() <= 256) |
| 145 |
2/2✓ Branch 23 → 14 taken 34 times.
✓ Branch 23 → 24 taken 17 times.
|
51 | for (const auto &item : items) |
| 146 | 34 | values.append({item.path, item.displayName, item.color, item.supportedComponents, item.readOnly, | |
| 147 | 34 | item.push.capability == DavPushCapability::Supported}); | |
| 148 |
2/4✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 17 times.
✗ Branch 28 → 30 not taken.
✓ Branch 30 → 31 taken 17 times.
|
17 | guard->received(true, values, items.size() > 256 ? tr("Too many collections were returned.") : QString{}); |
| 149 |
1/9✓ Branch 19 → 20 taken 34 times.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
|
51 | }); |
| 150 |
1/3✓ Branch 57 → 58 taken 17 times.
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 127 not taken.
|
17 | connect(books, &CardDavClient::addressBooksDiscovered, m_request, [guard, generation](const QList<AddressBookInfo> &items) { |
| 151 |
3/6✓ Branch 3 → 4 taken 16 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 16 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 16 times.
|
16 | if (!guard || guard->m_generation != generation) return; |
| 152 | 16 | QList<Item> values; | |
| 153 |
1/2✓ Branch 11 → 12 taken 16 times.
✗ Branch 11 → 23 not taken.
|
16 | if (items.size() <= 256) |
| 154 |
2/2✓ Branch 21 → 14 taken 16 times.
✓ Branch 21 → 22 taken 16 times.
|
32 | for (const auto &item : items) |
| 155 | 16 | values.append({item.path, item.displayName, QString(), {}, item.readOnly, | |
| 156 | 16 | item.push.capability == DavPushCapability::Supported}); | |
| 157 |
2/4✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 16 times.
✗ Branch 26 → 28 not taken.
✓ Branch 28 → 29 taken 16 times.
|
16 | guard->received(false, values, items.size() > 256 ? tr("Too many collections were returned.") : QString{}); |
| 158 |
1/9✓ Branch 17 → 18 taken 16 times.
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 38 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 44 not taken.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 47 not taken.
|
32 | }); |
| 159 |
1/3✓ Branch 62 → 63 taken 17 times.
✗ Branch 132 → 133 not taken.
✗ Branch 132 → 134 not taken.
|
17 | connect(calendar, &CalDavClient::syncFailed, m_request, [guard, generation](const QString &message) { |
| 160 | ✗ | if (guard && guard->m_generation == generation) guard->received(true, {}, message.left(1024)); | |
| 161 | ✗ | }); | |
| 162 |
1/3✓ Branch 67 → 68 taken 17 times.
✗ Branch 139 → 140 not taken.
✗ Branch 139 → 141 not taken.
|
17 | connect(books, &CardDavClient::syncFailed, m_request, [guard, generation](const QString &message) { |
| 163 |
5/8✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 16 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
|
1 | if (guard && guard->m_generation == generation) guard->received(false, {}, message.left(1024)); |
| 164 | 1 | }); | |
| 165 |
1/1✓ Branch 70 → 71 taken 17 times.
|
17 | emit stateChanged(); |
| 166 |
3/6✓ Branch 72 → 73 taken 17 times.
✗ Branch 72 → 75 not taken.
✗ Branch 74 → 75 not taken.
✓ Branch 74 → 76 taken 17 times.
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 79 taken 17 times.
|
17 | if (!guard || guard->m_generation != generation) return; |
| 167 |
1/1✓ Branch 79 → 80 taken 17 times.
|
17 | calendar->discoverCalendars(); |
| 168 |
4/7✓ Branch 81 → 82 taken 17 times.
✗ Branch 81 → 85 not taken.
✓ Branch 83 → 84 taken 17 times.
✗ Branch 83 → 85 not taken.
✓ Branch 86 → 87 taken 17 times.
✗ Branch 86 → 88 not taken.
✓ Branch 87 → 88 taken 17 times.
|
17 | if (guard && guard->m_generation == generation) books->discoverAddressBooks(); |
| 169 | 17 | } | |
| 170 | 34 | void DavCollectionDiscovery::received(bool calendars, const QList<Item> &values, const QString &error) { | |
| 171 |
6/8✓ Branch 2 → 3 taken 17 times.
✓ Branch 2 → 4 taken 17 times.
✓ Branch 3 → 4 taken 17 times.
✗ Branch 3 → 6 not taken.
✓ Branch 4 → 5 taken 17 times.
✓ Branch 4 → 7 taken 17 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 17 times.
|
34 | if ((calendars && m_calendarsDone) || (!calendars && m_booksDone)) return; |
| 172 |
2/5✓ Branch 7 → 8 taken 34 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 13 taken 34 times.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
|
34 | if (!currentConfiguration()) { fail(tr("The account settings changed. Discover its collections again.")); return; } |
| 173 |
2/2✓ Branch 13 → 14 taken 17 times.
✓ Branch 13 → 15 taken 17 times.
|
34 | auto &target = calendars ? m_calendars : m_books; |
| 174 |
2/2✓ Branch 16 → 17 taken 17 times.
✓ Branch 16 → 18 taken 17 times.
|
34 | auto &failure = calendars ? m_calendarError : m_bookError; |
| 175 | 34 | failure = error; | |
| 176 | 34 | QSet<QString> keys; | |
| 177 |
4/4✓ Branch 22 → 23 taken 33 times.
✓ Branch 22 → 59 taken 1 time.
✓ Branch 57 → 25 taken 50 times.
✓ Branch 57 → 58 taken 32 times.
|
83 | if (failure.isEmpty()) for (const auto &item : values) { |
| 178 |
2/2✓ Branch 26 → 27 taken 50 times.
✓ Branch 27 → 28 taken 50 times.
|
50 | const QString key = collectionKey(item.path.trimmed()); |
| 179 |
3/3✓ Branch 30 → 31 taken 1 time.
✓ Branch 30 → 35 taken 49 times.
✓ Branch 31 → 32 taken 1 time.
|
50 | if (key.isEmpty()) { failure = tr("The server returned an invalid collection address."); break; } |
| 180 |
1/2✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 49 times.
|
49 | if (keys.contains(key)) continue; |
| 181 |
1/1✓ Branch 38 → 39 taken 49 times.
|
49 | keys.insert(key); |
| 182 |
3/7✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 49 times.
✗ Branch 41 → 43 not taken.
✓ Branch 42 → 43 taken 49 times.
✓ Branch 43 → 44 taken 49 times.
✗ Branch 82 → 83 not taken.
✗ Branch 82 → 84 not taken.
|
49 | Row row{item.name.isEmpty() ? item.path.left(512) : item.name.left(512), item.path.trimmed(), calendars, false, true, false}; |
| 183 | 49 | row.color = item.color; | |
| 184 | 49 | row.components = item.components; | |
| 185 | 49 | row.readOnly = item.readOnly; | |
| 186 | 49 | row.push = item.push; | |
| 187 |
1/1✓ Branch 46 → 47 taken 49 times.
|
49 | target.append(row); |
| 188 | 50 | } | |
| 189 |
3/3✓ Branch 60 → 61 taken 2 times.
✓ Branch 60 → 62 taken 32 times.
✓ Branch 61 → 62 taken 2 times.
|
34 | if (!failure.isEmpty()) target.clear(); |
| 190 |
2/2✓ Branch 62 → 63 taken 17 times.
✓ Branch 62 → 65 taken 17 times.
|
34 | if (calendars) { m_calendarsDone = true; m_calendarsOk = failure.isEmpty(); } |
| 191 | 17 | else { m_booksDone = true; m_booksOk = failure.isEmpty(); } | |
| 192 |
4/5✓ Branch 67 → 68 taken 34 times.
✗ Branch 67 → 70 not taken.
✓ Branch 68 → 69 taken 17 times.
✓ Branch 68 → 70 taken 17 times.
✓ Branch 69 → 70 taken 17 times.
|
34 | if (m_calendarsDone && m_booksDone) completeEnumeration(); |
| 193 | 34 | } | |
| 194 | 17 | void DavCollectionDiscovery::completeEnumeration() { | |
| 195 |
1/4✗ Branch 2 → 3 not taken.
✓ Branch 2 → 20 taken 17 times.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 20 not taken.
|
17 | if (!m_calendarsOk && !m_booksOk) { |
| 196 | ✗ | fail(tr("No collections could be discovered.") + QLatin1Char('\n') + m_calendarError + QLatin1Char('\n') + m_bookError); | |
| 197 | ✗ | return; | |
| 198 | } | ||
| 199 | 32 | const auto retainSelections = [this](QList<Row> &rows, const QStringList &selected, bool calendar) { | |
| 200 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 32 times.
|
32 | if (selected.size() > 256) return false; |
| 201 | 32 | QSet<QString> found; | |
| 202 |
4/4✓ Branch 6 → 7 taken 32 times.
✓ Branch 7 → 8 taken 32 times.
✓ Branch 26 → 9 taken 49 times.
✓ Branch 26 → 27 taken 32 times.
|
81 | for (auto &row : rows) { |
| 203 |
6/6✓ Branch 13 → 14 taken 2 times.
✓ Branch 14 → 15 taken 2 times.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 21 taken 1 time.
✓ Branch 23 → 12 taken 2 times.
✓ Branch 23 → 24 taken 49 times.
|
51 | for (const auto &path : selected) if (collectionKey(path) == collectionKey(row.path)) { |
| 204 |
1/1✓ Branch 19 → 20 taken 1 time.
|
1 | row.selected = row.initiallySelected = true; found.insert(path); |
| 205 | } | ||
| 206 | } | ||
| 207 |
4/4✓ Branch 31 → 32 taken 1 time.
✓ Branch 31 → 37 taken 1 time.
✓ Branch 39 → 29 taken 2 times.
✓ Branch 39 → 40 taken 32 times.
|
34 | for (const auto &path : selected) if (!found.contains(path)) |
| 208 | 1 | rows.append({path.left(512), path, calendar, true, false, true}); | |
| 209 | 32 | return rows.size() <= 256; | |
| 210 |
2/6✓ Branch 32 → 33 taken 1 time.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
|
33 | }; |
| 211 |
4/7✓ Branch 20 → 21 taken 17 times.
✗ Branch 20 → 23 not taken.
✓ Branch 21 → 22 taken 17 times.
✓ Branch 22 → 23 taken 17 times.
✗ Branch 22 → 26 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 33 taken 17 times.
|
34 | if ((m_calendarsOk && !retainSelections(m_calendars, m_calendarConfig.selectedCalendars, true)) || |
| 212 |
4/5✓ Branch 23 → 24 taken 15 times.
✓ Branch 23 → 27 taken 2 times.
✓ Branch 24 → 25 taken 15 times.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 15 times.
|
17 | (m_booksOk && !retainSelections(m_books, m_account.selectedBooks, false))) { |
| 213 | ✗ | fail(tr("Too many collections were returned.")); return; | |
| 214 | } | ||
| 215 |
1/1✓ Branch 33 → 34 taken 17 times.
|
17 | stopRequest(); |
| 216 |
1/1✓ Branch 34 → 35 taken 17 times.
|
17 | beginResetModel(); |
| 217 |
1/1✓ Branch 35 → 36 taken 17 times.
|
17 | m_rows = m_calendars + m_books; |
| 218 |
1/1✓ Branch 38 → 39 taken 17 times.
|
17 | endResetModel(); |
| 219 | 17 | m_state = QStringLiteral("ready"); m_dirty = false; | |
| 220 |
1/1✓ Branch 45 → 46 taken 17 times.
|
17 | writeCache(); |
| 221 |
1/1✓ Branch 47 → 48 taken 17 times.
|
17 | rememberKnown({}); // the first discovery of an account offers nothing as new |
| 222 | 17 | QStringList errors; | |
| 223 |
1/5✗ Branch 50 → 51 not taken.
✓ Branch 50 → 58 taken 17 times.
✗ Branch 51 → 52 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 54 → 55 not taken.
|
17 | if (!m_calendarError.isEmpty()) errors.append(tr("Calendars: %1").arg(m_calendarError)); |
| 224 |
5/5✓ Branch 59 → 60 taken 2 times.
✓ Branch 59 → 67 taken 15 times.
✓ Branch 60 → 61 taken 2 times.
✓ Branch 62 → 63 taken 2 times.
✓ Branch 63 → 64 taken 2 times.
|
19 | if (!m_bookError.isEmpty()) errors.append(tr("Address books: %1").arg(m_bookError)); |
| 225 |
1/1✓ Branch 69 → 70 taken 17 times.
|
17 | m_error = errors.join(QLatin1Char('\n')); |
| 226 |
1/1✓ Branch 72 → 73 taken 17 times.
|
17 | emit stateChanged(); |
| 227 | 17 | } | |
| 228 | 19 | bool DavCollectionDiscovery::setSelected(int row, bool selected) { | |
| 229 |
4/8✓ Branch 2 → 3 taken 19 times.
✗ Branch 2 → 11 not taken.
✓ Branch 3 → 4 taken 19 times.
✗ Branch 3 → 11 not taken.
✓ Branch 5 → 6 taken 19 times.
✗ Branch 5 → 11 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 19 times.
|
38 | if (m_busy || row < 0 || row >= m_rows.size() || |
| 230 |
7/8✓ Branch 6 → 7 taken 19 times.
✓ Branch 7 → 8 taken 3 times.
✓ Branch 7 → 12 taken 16 times.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 12 taken 2 times.
✓ Branch 9 → 10 taken 1 time.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 1 time.
|
19 | (!m_rows[row].available && selected && !m_rows[row].initiallySelected)) return false; |
| 231 |
1/1✓ Branch 15 → 16 taken 19 times.
|
19 | m_rows[row].selected = selected; |
| 232 | 19 | m_dirty = false; | |
| 233 |
4/4✓ Branch 16 → 17 taken 19 times.
✓ Branch 17 → 18 taken 19 times.
✓ Branch 22 → 19 taken 58 times.
✓ Branch 22 → 23 taken 19 times.
|
77 | for (const auto &item : m_rows) m_dirty |= item.selected != item.initiallySelected; |
| 234 |
1/1✓ Branch 23 → 24 taken 19 times.
|
19 | QPointer<DavCollectionDiscovery> guard(this); |
| 235 |
4/4✓ Branch 24 → 25 taken 19 times.
✓ Branch 26 → 27 taken 19 times.
✓ Branch 28 → 29 taken 19 times.
✓ Branch 29 → 30 taken 19 times.
|
19 | emit dataChanged(index(row), index(row), {Selected}); |
| 236 |
2/3✓ Branch 32 → 33 taken 19 times.
✗ Branch 32 → 34 not taken.
✓ Branch 33 → 34 taken 19 times.
|
19 | if (guard) emit stateChanged(); |
| 237 | 19 | return true; | |
| 238 | 19 | } | |
| 239 | 15 | bool DavCollectionDiscovery::apply() { | |
| 240 |
8/8✓ Branch 3 → 4 taken 14 times.
✓ Branch 3 → 6 taken 1 time.
✓ Branch 4 → 5 taken 14 times.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 13 times.
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 11 taken 13 times.
✓ Branch 9 → 10 taken 2 times.
|
15 | if (!canApply() || !currentConfiguration()) { invalidateConfiguration(); return false; } |
| 241 | 13 | QStringList books, calendars; | |
| 242 |
6/6✓ Branch 11 → 12 taken 13 times.
✓ Branch 12 → 13 taken 13 times.
✓ Branch 15 → 16 taken 13 times.
✓ Branch 15 → 29 taken 25 times.
✓ Branch 31 → 14 taken 38 times.
✓ Branch 31 → 32 taken 13 times.
|
51 | for (const auto &row : m_rows) if (row.selected) { |
| 243 |
2/5✓ Branch 16 → 17 taken 13 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 25 taken 13 times.
✗ Branch 20 → 21 not taken.
✗ Branch 23 → 24 not taken.
|
13 | if (collectionKey(row.path).isEmpty()) { m_error = tr("Deselect unavailable collections before saving."); emit stateChanged(); return false; } |
| 244 |
3/3✓ Branch 25 → 26 taken 10 times.
✓ Branch 25 → 27 taken 3 times.
✓ Branch 28 → 29 taken 13 times.
|
13 | (row.calendar ? calendars : books).append(row.path); |
| 245 | } | ||
| 246 |
1/1✓ Branch 39 → 40 taken 13 times.
|
13 | if (!DavAccountSettings::storeSelections(m_account, m_calendarConfig, |
| 247 |
2/2✓ Branch 36 → 37 taken 11 times.
✓ Branch 36 → 38 taken 2 times.
|
26 | m_booksOk ? std::optional<QStringList>(books) : std::nullopt, |
| 248 |
2/4✓ Branch 32 → 34 taken 13 times.
✗ Branch 32 → 35 not taken.
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 48 taken 13 times.
|
26 | m_calendarsOk ? std::optional<QStringList>(calendars) : std::nullopt)) { |
| 249 | ✗ | m_error = tr("The collection selection could not be saved. Discover again if the account changed."); | |
| 250 | ✗ | emit stateChanged(); return false; | |
| 251 | } | ||
| 252 |
2/2✓ Branch 48 → 49 taken 11 times.
✓ Branch 48 → 50 taken 2 times.
|
13 | if (m_booksOk) m_account.selectedBooks = books; |
| 253 |
1/2✓ Branch 50 → 51 taken 13 times.
✗ Branch 50 → 52 not taken.
|
13 | if (m_calendarsOk) m_calendarConfig.selectedCalendars = calendars; |
| 254 |
4/4✓ Branch 52 → 53 taken 13 times.
✓ Branch 53 → 54 taken 13 times.
✓ Branch 58 → 55 taken 38 times.
✓ Branch 58 → 59 taken 13 times.
|
51 | for (auto &row : m_rows) row.initiallySelected = row.selected; |
| 255 | 26 | m_dirty = false; m_state = QStringLiteral("saved"); | |
| 256 | 13 | const auto id = m_account.id; | |
| 257 | 13 | const auto generation = m_generation; | |
| 258 |
1/1✓ Branch 66 → 67 taken 13 times.
|
13 | QPointer<DavCollectionDiscovery> guard(this); |
| 259 |
1/1✓ Branch 67 → 68 taken 13 times.
|
13 | emit stateChanged(); |
| 260 |
4/7✓ Branch 69 → 70 taken 13 times.
✗ Branch 69 → 72 not taken.
✓ Branch 70 → 71 taken 13 times.
✗ Branch 70 → 72 not taken.
✓ Branch 73 → 74 taken 13 times.
✗ Branch 73 → 75 not taken.
✓ Branch 74 → 75 taken 13 times.
|
13 | if (guard && generation == m_generation) emit applied(id); |
| 261 | 13 | return true; | |
| 262 | 13 | } | |
| 263 | |||
| 264 | // ─── Sprint 100 S100.1.12/S100.1.13: what a collection is, instant toggles, | ||
| 265 | // the last known list and what is new on the server ─── | ||
| 266 | |||
| 267 | 15 | QString DavCollectionDiscovery::contentKind(const Row &row) const { | |
| 268 | 15 | return kindOf(row.calendar, row.components); | |
| 269 | } | ||
| 270 | 612 | QString DavCollectionDiscovery::kindOf(bool calendar, const QStringList &components) { | |
| 271 |
2/2✓ Branch 2 → 3 taken 125 times.
✓ Branch 2 → 8 taken 487 times.
|
737 | if (!calendar) return QStringLiteral("book"); |
| 272 |
8/8✓ Branch 9 → 10 taken 240 times.
✓ Branch 9 → 15 taken 247 times.
✓ Branch 14 → 15 taken 226 times.
✓ Branch 14 → 16 taken 14 times.
✓ Branch 17 → 18 taken 240 times.
✓ Branch 17 → 19 taken 247 times.
✓ Branch 19 → 20 taken 240 times.
✓ Branch 19 → 21 taken 247 times.
|
727 | const bool events = components.isEmpty() || components.contains(QStringLiteral("VEVENT")); |
| 273 | 487 | const bool tasks = components.contains(QStringLiteral("VTODO")); | |
| 274 |
3/4✓ Branch 27 → 28 taken 473 times.
✓ Branch 27 → 34 taken 14 times.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 34 taken 473 times.
|
487 | if (events && tasks) return QStringLiteral("both"); |
| 275 |
6/6✓ Branch 34 → 35 taken 14 times.
✓ Branch 34 → 38 taken 473 times.
✓ Branch 42 → 43 taken 473 times.
✓ Branch 42 → 44 taken 14 times.
✓ Branch 44 → 45 taken 14 times.
✓ Branch 44 → 46 taken 473 times.
|
1461 | return tasks ? QStringLiteral("tasks") : QStringLiteral("calendar"); |
| 276 | } | ||
| 277 | |||
| 278 | 22 | QString DavCollectionDiscovery::defaultOffReason(const QString &path, bool calendar) { | |
| 279 | // Nextcloud's address book of every user of the instance, and server-made | ||
| 280 | // birthday calendars (MailJD shows birthdays itself, S97.5.10). | ||
| 281 |
7/7✓ Branch 2 → 3 taken 6 times.
✓ Branch 2 → 7 taken 16 times.
✓ Branch 4 → 5 taken 6 times.
✓ Branch 5 → 6 taken 3 times.
✓ Branch 5 → 7 taken 3 times.
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 10 taken 19 times.
|
22 | if (!calendar && path.contains(QLatin1String("z-server-generated--system"))) |
| 282 | 3 | return tr("All users of the server; off by default."); | |
| 283 |
7/7✓ Branch 10 → 11 taken 16 times.
✓ Branch 10 → 15 taken 3 times.
✓ Branch 12 → 13 taken 16 times.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 15 taken 14 times.
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 17 times.
|
19 | if (calendar && path.contains(QLatin1String("contact_birthdays"))) |
| 284 | 2 | return tr("Birthdays from the server; MailJD shows them from your contacts."); | |
| 285 | 17 | return {}; | |
| 286 | } | ||
| 287 | |||
| 288 | 10 | QVariantMap DavCollectionDiscovery::toggle(int row, bool selected) { | |
| 289 |
3/10✓ Branch 2 → 3 taken 10 times.
✗ Branch 2 → 5 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 10 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 19 taken 10 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
✗ Branch 152 → 153 not taken.
✗ Branch 152 → 154 not taken.
|
10 | if (row < 0 || row >= m_rows.size()) return {{QStringLiteral("ok"), false}}; |
| 290 | 10 | const Row item = m_rows.at(row); | |
| 291 |
7/8✓ Branch 21 → 22 taken 3 times.
✓ Branch 21 → 26 taken 7 times.
✓ Branch 22 → 23 taken 3 times.
✗ Branch 22 → 26 not taken.
✓ Branch 24 → 25 taken 2 times.
✓ Branch 24 → 26 taken 1 time.
✓ Branch 27 → 28 taken 2 times.
✓ Branch 27 → 54 taken 8 times.
|
10 | if (!selected && item.selected && m_pendingCounter) { |
| 292 |
1/1✓ Branch 28 → 29 taken 2 times.
|
2 | const int pending = m_pendingCounter(m_account.id, item.path, item.calendar); |
| 293 |
2/2✓ Branch 29 → 30 taken 1 time.
✓ Branch 29 → 53 taken 1 time.
|
2 | if (pending > 0) |
| 294 |
2/4✓ Branch 44 → 45 taken 3 times.
✓ Branch 44 → 46 taken 1 time.
✗ Branch 169 → 170 not taken.
✗ Branch 169 → 171 not taken.
|
8 | return {{QStringLiteral("ok"), false}, {QStringLiteral("pending"), pending}, {QStringLiteral("name"), item.name}}; |
| 295 | } | ||
| 296 |
4/6✓ Branch 56 → 57 taken 1 time.
✓ Branch 56 → 74 taken 8 times.
✓ Branch 67 → 68 taken 2 times.
✓ Branch 67 → 69 taken 1 time.
✗ Branch 199 → 200 not taken.
✗ Branch 199 → 201 not taken.
|
15 | if (m_state == QLatin1String("cached")) return {{QStringLiteral("ok"), false}, {QStringLiteral("name"), item.name}}; |
| 297 |
2/7✓ Branch 74 → 75 taken 8 times.
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 93 taken 8 times.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 88 not taken.
✗ Branch 222 → 223 not taken.
✗ Branch 222 → 224 not taken.
|
8 | if (!setSelected(row, selected)) return {{QStringLiteral("ok"), false}, {QStringLiteral("name"), item.name}}; |
| 298 |
4/11✓ Branch 93 → 94 taken 8 times.
✗ Branch 93 → 97 not taken.
✓ Branch 94 → 95 taken 8 times.
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 97 taken 8 times.
✗ Branch 98 → 99 not taken.
✓ Branch 98 → 116 taken 8 times.
✗ Branch 109 → 110 not taken.
✗ Branch 109 → 111 not taken.
✗ Branch 245 → 246 not taken.
✗ Branch 245 → 247 not taken.
|
8 | if (m_dirty && !apply()) return {{QStringLiteral("ok"), false}, {QStringLiteral("name"), item.name}}; |
| 299 |
5/7✓ Branch 116 → 117 taken 6 times.
✓ Branch 116 → 125 taken 2 times.
✓ Branch 119 → 120 taken 6 times.
✓ Branch 122 → 123 taken 6 times.
✓ Branch 122 → 124 taken 6 times.
✗ Branch 270 → 271 not taken.
✗ Branch 270 → 272 not taken.
|
20 | if (selected) rememberKnown({collectionKey(item.path)}); |
| 300 |
2/4✓ Branch 139 → 140 taken 24 times.
✓ Branch 139 → 141 taken 8 times.
✗ Branch 281 → 282 not taken.
✗ Branch 281 → 283 not taken.
|
64 | return {{QStringLiteral("ok"), true}, {QStringLiteral("name"), item.name}, {QStringLiteral("selected"), selected}}; |
| 301 | 65 | } | |
| 302 | |||
| 303 | 1 | int DavCollectionDiscovery::selectDefaults() { | |
| 304 | 1 | int selected = 0; | |
| 305 |
2/2✓ Branch 20 → 3 taken 3 times.
✓ Branch 20 → 21 taken 1 time.
|
4 | for (int row = 0; row < m_rows.size(); ++row) { |
| 306 |
5/9✓ Branch 4 → 5 taken 3 times.
✗ Branch 4 → 11 not taken.
✓ Branch 7 → 8 taken 3 times.
✓ Branch 9 → 10 taken 2 times.
✓ Branch 9 → 11 taken 1 time.
✓ Branch 12 → 13 taken 3 times.
✗ Branch 12 → 14 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
|
3 | const bool on = m_rows.at(row).available && defaultOffReason(m_rows.at(row).path, m_rows.at(row).calendar).isEmpty(); |
| 307 | 3 | setSelected(row, on); | |
| 308 |
2/2✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 17 taken 1 time.
|
3 | selected += on ? 1 : 0; |
| 309 | } | ||
| 310 |
1/2✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 23 not taken.
|
1 | if (m_dirty) apply(); |
| 311 | 1 | return selected; | |
| 312 | } | ||
| 313 | |||
| 314 | namespace { | ||
| 315 |
1/1✓ Branch 5 → 6 taken 1450 times.
|
2900 | QString knownName(const QString &accountId) { return QStringLiteral("carddav/collectionKnown/") + accountId; } |
| 316 |
1/1✓ Branch 5 → 6 taken 69 times.
|
138 | QString seededName(const QString &accountId) { return QStringLiteral("carddav/collectionSeeded/") + accountId; } |
| 317 |
1/1✓ Branch 5 → 6 taken 1424 times.
|
2848 | QString cacheName(const QString &accountId) { return QStringLiteral("carddav/collectionCache/") + accountId; } |
| 318 | // The kinds ("calendars", "books") whose first list is already in the known | ||
| 319 | // set. A known set from before the per-kind record came from a complete | ||
| 320 | // discovery, so it covers both. | ||
| 321 | 32 | QStringList seededKinds(const QString &accountId) { | |
| 322 |
1/1✓ Branch 2 → 3 taken 32 times.
|
32 | QSettings settings; |
| 323 |
7/7✓ Branch 3 → 4 taken 32 times.
✓ Branch 5 → 6 taken 32 times.
✓ Branch 7 → 8 taken 18 times.
✓ Branch 7 → 16 taken 14 times.
✓ Branch 8 → 9 taken 18 times.
✓ Branch 10 → 11 taken 18 times.
✓ Branch 11 → 12 taken 18 times.
|
32 | if (settings.contains(seededName(accountId))) return settings.value(seededName(accountId)).toStringList(); |
| 324 |
3/8✓ Branch 16 → 17 taken 14 times.
✓ Branch 18 → 19 taken 14 times.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 14 times.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 62 not taken.
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 66 not taken.
|
28 | return settings.contains(knownName(accountId)) ? QStringList{QStringLiteral("calendars"), QStringLiteral("books")} |
| 325 |
3/12✗ Branch 19 → 20 not taken.
✓ Branch 19 → 27 taken 14 times.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 33 taken 14 times.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 33 not taken.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 14 times.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 58 not taken.
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 58 not taken.
|
14 | : QStringList{}; |
| 326 | 32 | } | |
| 327 | // Adds the keys of the kinds not seeded yet (the first list of a kind | ||
| 328 | // offers nothing as new) and `keys` (added or dismissed) to the known set. | ||
| 329 | 32 | QStringList storeKnown(const QString &accountId, const QHash<QString, QStringList> &firstLists, const QStringList &keys) { | |
| 330 |
1/1✓ Branch 2 → 3 taken 32 times.
|
32 | QSettings settings; |
| 331 |
3/3✓ Branch 3 → 4 taken 32 times.
✓ Branch 5 → 6 taken 32 times.
✓ Branch 6 → 7 taken 32 times.
|
32 | QStringList known = settings.value(knownName(accountId)).toStringList(); |
| 332 |
1/1✓ Branch 9 → 10 taken 32 times.
|
32 | QStringList seeded = seededKinds(accountId); |
| 333 | 32 | bool changed = false; | |
| 334 |
2/2✓ Branch 36 → 11 taken 38 times.
✓ Branch 36 → 37 taken 32 times.
|
70 | for (auto it = firstLists.cbegin(); it != firstLists.cend(); ++it) { |
| 335 |
2/2✓ Branch 13 → 14 taken 13 times.
✓ Branch 13 → 15 taken 25 times.
|
38 | if (seeded.contains(it.key())) continue; |
| 336 |
1/1✓ Branch 16 → 17 taken 25 times.
|
25 | seeded << it.key(); |
| 337 |
6/9✓ Branch 22 → 23 taken 38 times.
✗ Branch 22 → 26 not taken.
✓ Branch 24 → 25 taken 38 times.
✗ Branch 24 → 26 not taken.
✓ Branch 27 → 28 taken 38 times.
✗ Branch 27 → 29 not taken.
✓ Branch 28 → 29 taken 38 times.
✓ Branch 31 → 20 taken 38 times.
✓ Branch 31 → 32 taken 25 times.
|
63 | for (const auto &key : it.value()) if (!key.isEmpty() && !known.contains(key)) known << key; |
| 338 | 25 | changed = true; | |
| 339 | } | ||
| 340 |
2/2✓ Branch 51 → 39 taken 9 times.
✓ Branch 51 → 52 taken 32 times.
|
41 | for (const auto &key : keys) |
| 341 |
6/7✓ Branch 41 → 42 taken 9 times.
✗ Branch 41 → 45 not taken.
✓ Branch 43 → 44 taken 4 times.
✓ Branch 43 → 45 taken 5 times.
✓ Branch 46 → 47 taken 4 times.
✓ Branch 46 → 49 taken 5 times.
✓ Branch 47 → 48 taken 4 times.
|
9 | if (!key.isEmpty() && !known.contains(key)) { known << key; changed = true; } |
| 342 |
2/2✓ Branch 52 → 53 taken 19 times.
✓ Branch 52 → 66 taken 13 times.
|
32 | if (changed) { |
| 343 |
2/2✓ Branch 54 → 55 taken 19 times.
✓ Branch 56 → 57 taken 19 times.
|
19 | settings.setValue(knownName(accountId), known); |
| 344 |
2/2✓ Branch 60 → 61 taken 19 times.
✓ Branch 62 → 63 taken 19 times.
|
19 | settings.setValue(seededName(accountId), seeded); |
| 345 | } | ||
| 346 | 32 | return known; | |
| 347 | 32 | } | |
| 348 | } // namespace | ||
| 349 | |||
| 350 | 17 | void DavCollectionDiscovery::writeCache() const { | |
| 351 |
1/1✓ Branch 2 → 3 taken 17 times.
|
17 | QJsonArray rows; |
| 352 |
2/2✓ Branch 28 → 5 taken 50 times.
✓ Branch 28 → 29 taken 17 times.
|
67 | for (const auto &row : m_rows) { |
| 353 |
2/2✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 8 taken 49 times.
|
50 | if (!row.available) continue; |
| 354 |
1/1✓ Branch 18 → 19 taken 49 times.
|
49 | rows.append(QJsonObject{{"name", row.name}, {"path", row.path}, {"calendar", row.calendar}, {"color", row.color}, |
| 355 | 49 | {"components", QJsonArray::fromStringList(row.components)}, {"readOnly", row.readOnly}, | |
| 356 |
2/4✓ Branch 22 → 23 taken 343 times.
✓ Branch 22 → 24 taken 49 times.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 52 not taken.
|
441 | {"push", row.push}}); |
| 357 | } | ||
| 358 |
3/3✓ Branch 29 → 30 taken 17 times.
✓ Branch 34 → 35 taken 17 times.
✓ Branch 36 → 37 taken 17 times.
|
34 | QSettings().setValue(cacheName(m_account.id), |
| 359 |
3/3✓ Branch 30 → 31 taken 17 times.
✓ Branch 31 → 32 taken 17 times.
✓ Branch 32 → 33 taken 17 times.
|
34 | QString::fromUtf8(QJsonDocument(rows).toJson(QJsonDocument::Compact))); |
| 360 | 66 | } | |
| 361 | |||
| 362 | 8 | bool DavCollectionDiscovery::readCache() { | |
| 363 |
4/4✓ Branch 2 → 3 taken 8 times.
✓ Branch 3 → 4 taken 8 times.
✓ Branch 5 → 6 taken 8 times.
✓ Branch 6 → 7 taken 8 times.
|
8 | const QString text = QSettings().value(cacheName(m_account.id)).toString(); |
| 364 |
3/3✓ Branch 10 → 11 taken 8 times.
✓ Branch 11 → 12 taken 8 times.
✓ Branch 12 → 13 taken 8 times.
|
8 | const QJsonArray rows = QJsonDocument::fromJson(text.toUtf8()).array(); |
| 365 |
3/3✓ Branch 15 → 16 taken 8 times.
✓ Branch 16 → 17 taken 5 times.
✓ Branch 16 → 18 taken 3 times.
|
8 | if (rows.isEmpty()) return false; |
| 366 | 3 | QList<Row> list; | |
| 367 |
3/3✓ Branch 19 → 20 taken 3 times.
✓ Branch 94 → 21 taken 9 times.
✓ Branch 94 → 95 taken 3 times.
|
12 | for (const auto &value : rows) { |
| 368 |
1/1✓ Branch 22 → 23 taken 9 times.
|
9 | const auto object = value.toObject(); |
| 369 |
5/5✓ Branch 23 → 24 taken 9 times.
✓ Branch 24 → 25 taken 9 times.
✓ Branch 27 → 28 taken 9 times.
✓ Branch 30 → 31 taken 9 times.
✓ Branch 31 → 32 taken 9 times.
|
36 | Row row{object.value("name").toString(), object.value("path").toString(), object.value("calendar").toBool(), |
| 370 |
4/8✓ Branch 25 → 26 taken 9 times.
✓ Branch 26 → 27 taken 9 times.
✓ Branch 28 → 29 taken 9 times.
✓ Branch 29 → 30 taken 9 times.
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 127 not taken.
✗ Branch 134 → 135 not taken.
✗ Branch 134 → 136 not taken.
|
27 | false, true, false}; |
| 371 |
3/3✓ Branch 38 → 39 taken 9 times.
✓ Branch 39 → 40 taken 9 times.
✓ Branch 40 → 41 taken 9 times.
|
9 | row.color = object.value("color").toString(); |
| 372 |
9/9✓ Branch 45 → 46 taken 9 times.
✓ Branch 46 → 47 taken 9 times.
✓ Branch 47 → 48 taken 9 times.
✓ Branch 50 → 51 taken 9 times.
✓ Branch 51 → 52 taken 9 times.
✓ Branch 55 → 56 taken 6 times.
✓ Branch 56 → 57 taken 6 times.
✓ Branch 61 → 53 taken 6 times.
✓ Branch 61 → 62 taken 9 times.
|
15 | for (const auto &component : object.value("components").toArray()) row.components << component.toString(); |
| 373 |
3/3✓ Branch 63 → 64 taken 9 times.
✓ Branch 64 → 65 taken 9 times.
✓ Branch 65 → 66 taken 9 times.
|
9 | row.readOnly = object.value("readOnly").toBool(); |
| 374 |
3/3✓ Branch 68 → 69 taken 9 times.
✓ Branch 69 → 70 taken 9 times.
✓ Branch 70 → 71 taken 9 times.
|
9 | row.push = object.value("push").toBool(); |
| 375 |
2/2✓ Branch 73 → 74 taken 8 times.
✓ Branch 73 → 75 taken 1 time.
|
9 | const QStringList &selected = row.calendar ? m_calendarConfig.selectedCalendars : m_account.selectedBooks; |
| 376 |
1/2✗ Branch 88 → 78 not taken.
✓ Branch 88 → 89 taken 9 times.
|
9 | for (const auto &path : selected) |
| 377 | ✗ | if (collectionKey(path) == collectionKey(row.path)) row.selected = row.initiallySelected = true; | |
| 378 |
1/1✓ Branch 89 → 90 taken 9 times.
|
9 | list.append(row); |
| 379 | 9 | } | |
| 380 |
1/1✓ Branch 95 → 96 taken 3 times.
|
3 | beginResetModel(); |
| 381 | 3 | m_rows = list; | |
| 382 |
1/1✓ Branch 97 → 98 taken 3 times.
|
3 | endResetModel(); |
| 383 | 3 | return true; | |
| 384 | 8 | } | |
| 385 | |||
| 386 | 8 | bool DavCollectionDiscovery::open(const QString &accountId) { | |
| 387 | // Start the discovery (it captures the account), then show the cache | ||
| 388 | // until the server answers (state "cached": toggles wait for "ready"). | ||
| 389 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 8 times.
|
8 | if (!discover(accountId)) return false; |
| 390 |
2/2✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 14 taken 5 times.
|
8 | if (readCache()) { |
| 391 | 3 | m_state = QStringLiteral("cached"); | |
| 392 | 3 | emit stateChanged(); | |
| 393 | } | ||
| 394 | 8 | return true; | |
| 395 | } | ||
| 396 | |||
| 397 | // D-22: the collections an account had when it was first discovered, plus | ||
| 398 | // every collection the user added or dismissed since. Anything else that | ||
| 399 | // shows up on the server is "new" until it is added or dismissed. | ||
| 400 | |||
| 401 | 23 | void DavCollectionDiscovery::rememberKnown(const QStringList &keys) { | |
| 402 | 23 | QHash<QString, QStringList> firstLists; | |
| 403 |
2/2✓ Branch 3 → 4 taken 17 times.
✓ Branch 3 → 76 taken 6 times.
|
23 | if (keys.isEmpty()) { |
| 404 | // After a complete enumeration: the lists that arrived seed their kind. | ||
| 405 |
4/4✓ Branch 4 → 5 taken 17 times.
✓ Branch 5 → 6 taken 17 times.
✓ Branch 33 → 7 taken 50 times.
✓ Branch 33 → 34 taken 17 times.
|
67 | for (const auto &row : m_rows) { |
| 406 |
2/2✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 10 taken 49 times.
|
50 | if (!row.available) continue; |
| 407 |
3/4✓ Branch 10 → 11 taken 34 times.
✓ Branch 10 → 12 taken 15 times.
✓ Branch 13 → 14 taken 49 times.
✗ Branch 13 → 31 not taken.
|
49 | if (row.calendar ? m_calendarsOk : m_booksOk) |
| 408 |
9/13✓ Branch 14 → 15 taken 34 times.
✓ Branch 14 → 18 taken 15 times.
✓ Branch 21 → 22 taken 49 times.
✓ Branch 22 → 23 taken 49 times.
✓ Branch 23 → 24 taken 49 times.
✓ Branch 26 → 27 taken 15 times.
✓ Branch 26 → 28 taken 34 times.
✓ Branch 28 → 29 taken 34 times.
✓ Branch 28 → 30 taken 15 times.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 88 not taken.
✗ Branch 90 → 91 not taken.
✗ Branch 90 → 92 not taken.
|
98 | firstLists[row.calendar ? QStringLiteral("calendars") : QStringLiteral("books")] << collectionKey(row.path); |
| 409 | } | ||
| 410 |
5/12✓ Branch 34 → 35 taken 17 times.
✗ Branch 34 → 41 not taken.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 17 times.
✓ Branch 42 → 43 taken 17 times.
✗ Branch 42 → 44 not taken.
✓ Branch 44 → 45 taken 17 times.
✗ Branch 44 → 46 not taken.
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 55 taken 17 times.
✗ Branch 50 → 51 not taken.
✗ Branch 51 → 52 not taken.
|
34 | if (m_calendarsOk && !firstLists.contains(QStringLiteral("calendars"))) firstLists[QStringLiteral("calendars")] = {}; |
| 411 |
8/12✓ Branch 55 → 56 taken 15 times.
✓ Branch 55 → 62 taken 2 times.
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 62 taken 15 times.
✓ Branch 63 → 64 taken 15 times.
✓ Branch 63 → 65 taken 2 times.
✓ Branch 65 → 66 taken 15 times.
✓ Branch 65 → 67 taken 2 times.
✗ Branch 67 → 68 not taken.
✓ Branch 67 → 76 taken 17 times.
✗ Branch 71 → 72 not taken.
✗ Branch 72 → 73 not taken.
|
32 | if (m_booksOk && !firstLists.contains(QStringLiteral("books"))) firstLists[QStringLiteral("books")] = {}; |
| 412 | } | ||
| 413 |
1/1✓ Branch 76 → 77 taken 23 times.
|
23 | m_cachedKeys = storeKnown(m_account.id, firstLists, keys); |
| 414 | 23 | } | |
| 415 | |||
| 416 | 1385 | QStringList DavCollectionDiscovery::knownKeys(const QString &accountId) { | |
| 417 |
4/4✓ Branch 2 → 3 taken 1385 times.
✓ Branch 3 → 4 taken 1385 times.
✓ Branch 5 → 6 taken 1385 times.
✓ Branch 6 → 7 taken 1385 times.
|
1385 | return QSettings().value(knownName(accountId)).toStringList(); |
| 418 | } | ||
| 419 | |||
| 420 | 3 | void DavCollectionDiscovery::addKnown(const QString &accountId, const QStringList &keys) { | |
| 421 |
1/1✓ Branch 3 → 4 taken 3 times.
|
3 | storeKnown(accountId, {}, keys); |
| 422 | 3 | } | |
| 423 | |||
| 424 | 1387 | QList<DavCollectionDiscovery::CachedCollection> DavCollectionDiscovery::cachedCollections(const Account &account) { | |
| 425 | 1387 | QList<CachedCollection> result; | |
| 426 |
7/7✓ Branch 2 → 3 taken 1387 times.
✓ Branch 3 → 4 taken 1387 times.
✓ Branch 5 → 6 taken 1387 times.
✓ Branch 6 → 7 taken 1387 times.
✓ Branch 7 → 8 taken 1387 times.
✓ Branch 8 → 9 taken 1387 times.
✓ Branch 9 → 10 taken 1387 times.
|
1387 | const QJsonArray rows = QJsonDocument::fromJson(QSettings().value(cacheName(account.id)).toString().toUtf8()).array(); |
| 427 |
3/3✓ Branch 17 → 18 taken 1387 times.
✓ Branch 71 → 19 taken 597 times.
✓ Branch 71 → 72 taken 1387 times.
|
1984 | for (const auto &value : rows) { |
| 428 |
1/1✓ Branch 20 → 21 taken 597 times.
|
597 | const auto object = value.toObject(); |
| 429 | 597 | CachedCollection item; | |
| 430 |
3/3✓ Branch 21 → 22 taken 597 times.
✓ Branch 22 → 23 taken 597 times.
✓ Branch 23 → 24 taken 597 times.
|
597 | item.name = object.value("name").toString(); |
| 431 |
3/3✓ Branch 28 → 29 taken 597 times.
✓ Branch 29 → 30 taken 597 times.
✓ Branch 30 → 31 taken 597 times.
|
597 | item.path = object.value("path").toString(); |
| 432 |
3/3✓ Branch 35 → 36 taken 597 times.
✓ Branch 36 → 37 taken 597 times.
✓ Branch 37 → 38 taken 597 times.
|
597 | item.calendar = object.value("calendar").toBool(); |
| 433 |
9/9✓ Branch 40 → 41 taken 597 times.
✓ Branch 41 → 42 taken 597 times.
✓ Branch 42 → 43 taken 597 times.
✓ Branch 45 → 46 taken 597 times.
✓ Branch 46 → 47 taken 597 times.
✓ Branch 50 → 51 taken 234 times.
✓ Branch 51 → 52 taken 234 times.
✓ Branch 56 → 48 taken 234 times.
✓ Branch 56 → 57 taken 597 times.
|
831 | for (const auto &component : object.value("components").toArray()) item.components << component.toString(); |
| 434 |
1/1✓ Branch 58 → 59 taken 597 times.
|
597 | item.kind = kindOf(item.calendar, item.components); |
| 435 |
1/1✓ Branch 61 → 62 taken 597 times.
|
597 | item.key = keyFor(account.serverUrl, item.path); |
| 436 |
2/3✓ Branch 65 → 66 taken 597 times.
✗ Branch 65 → 67 not taken.
✓ Branch 66 → 67 taken 597 times.
|
597 | if (!item.key.isEmpty()) result.append(item); |
| 437 | 597 | } | |
| 438 | 1387 | return result; | |
| 439 | 1387 | } | |
| 440 | |||
| 441 | 6 | void DavCollectionDiscovery::recordCalendars(const Account &account, const QList<Item> &calendars) { | |
| 442 |
3/6✓ Branch 3 → 4 taken 6 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 6 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 6 times.
|
6 | if (account.id.isEmpty() || calendars.size() > 256) return; |
| 443 |
1/1✓ Branch 10 → 11 taken 6 times.
|
6 | QSettings settings; |
| 444 |
1/1✓ Branch 11 → 12 taken 6 times.
|
6 | QJsonArray rows; |
| 445 |
10/10✓ Branch 12 → 13 taken 6 times.
✓ Branch 14 → 15 taken 6 times.
✓ Branch 15 → 16 taken 6 times.
✓ Branch 16 → 17 taken 6 times.
✓ Branch 17 → 18 taken 6 times.
✓ Branch 18 → 19 taken 6 times.
✓ Branch 24 → 25 taken 6 times.
✓ Branch 25 → 26 taken 6 times.
✓ Branch 42 → 27 taken 11 times.
✓ Branch 42 → 43 taken 6 times.
|
17 | for (const auto &value : QJsonDocument::fromJson(settings.value(cacheName(account.id)).toString().toUtf8()).array()) |
| 446 |
8/8✓ Branch 28 → 29 taken 11 times.
✓ Branch 29 → 30 taken 11 times.
✓ Branch 30 → 31 taken 11 times.
✓ Branch 31 → 32 taken 11 times.
✓ Branch 35 → 36 taken 2 times.
✓ Branch 35 → 40 taken 9 times.
✓ Branch 36 → 37 taken 2 times.
✓ Branch 37 → 38 taken 2 times.
|
17 | if (!value.toObject().value("calendar").toBool()) rows.append(value); |
| 447 | 6 | QStringList keys; | |
| 448 |
2/2✓ Branch 91 → 46 taken 14 times.
✓ Branch 91 → 92 taken 6 times.
|
20 | for (const auto &item : calendars) { |
| 449 |
2/2✓ Branch 47 → 48 taken 14 times.
✓ Branch 48 → 49 taken 14 times.
|
14 | const QString key = keyFor(account.serverUrl, item.path.trimmed()); |
| 450 |
3/6✓ Branch 51 → 52 taken 14 times.
✗ Branch 51 → 54 not taken.
✗ Branch 53 → 54 not taken.
✓ Branch 53 → 55 taken 14 times.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 58 taken 14 times.
|
14 | if (key.isEmpty() || keys.contains(key)) continue; |
| 451 |
1/1✓ Branch 58 → 59 taken 14 times.
|
14 | keys << key; |
| 452 |
3/5✗ Branch 60 → 61 not taken.
✓ Branch 60 → 62 taken 14 times.
✗ Branch 61 → 63 not taken.
✓ Branch 62 → 63 taken 14 times.
✓ Branch 74 → 75 taken 14 times.
|
28 | rows.append(QJsonObject{{"name", item.name.isEmpty() ? item.path.left(512) : item.name.left(512)}, |
| 453 | 14 | {"path", item.path.trimmed()}, {"calendar", true}, {"color", item.color}, | |
| 454 | 14 | {"components", QJsonArray::fromStringList(item.components)}, {"readOnly", item.readOnly}, | |
| 455 |
2/4✓ Branch 78 → 79 taken 98 times.
✓ Branch 78 → 80 taken 14 times.
✗ Branch 165 → 166 not taken.
✗ Branch 165 → 167 not taken.
|
112 | {"push", item.push}}); |
| 456 | 14 | } | |
| 457 |
5/5✓ Branch 92 → 93 taken 6 times.
✓ Branch 93 → 94 taken 6 times.
✓ Branch 94 → 95 taken 6 times.
✓ Branch 96 → 97 taken 6 times.
✓ Branch 98 → 99 taken 6 times.
|
6 | settings.setValue(cacheName(account.id), QString::fromUtf8(QJsonDocument(rows).toJson(QJsonDocument::Compact))); |
| 458 |
3/5✓ Branch 110 → 111 taken 6 times.
✓ Branch 114 → 115 taken 6 times.
✓ Branch 114 → 116 taken 6 times.
✗ Branch 209 → 210 not taken.
✗ Branch 209 → 211 not taken.
|
24 | storeKnown(account.id, {{QStringLiteral("calendars"), keys}}, {}); |
| 459 | 60 | } | |
| 460 | |||
| 461 | 47 | QVariantList DavCollectionDiscovery::newCollections() const { | |
| 462 |
6/6✓ Branch 4 → 5 taken 39 times.
✓ Branch 4 → 9 taken 8 times.
✓ Branch 7 → 8 taken 35 times.
✓ Branch 7 → 9 taken 4 times.
✓ Branch 10 → 11 taken 35 times.
✓ Branch 10 → 12 taken 12 times.
|
47 | if (m_state != QLatin1String("ready") && m_state != QLatin1String("saved")) return {}; |
| 463 | 12 | QVariantList result; | |
| 464 |
2/2✓ Branch 45 → 14 taken 36 times.
✓ Branch 45 → 46 taken 12 times.
|
48 | for (const auto &row : m_rows) { |
| 465 |
1/1✓ Branch 15 → 16 taken 36 times.
|
36 | const QString key = collectionKey(row.path); |
| 466 |
7/8✓ Branch 16 → 17 taken 28 times.
✓ Branch 16 → 20 taken 8 times.
✓ Branch 17 → 18 taken 28 times.
✗ Branch 17 → 20 not taken.
✓ Branch 19 → 20 taken 25 times.
✓ Branch 19 → 21 taken 3 times.
✓ Branch 22 → 23 taken 33 times.
✓ Branch 22 → 24 taken 3 times.
|
36 | if (row.selected || !row.available || m_cachedKeys.contains(key)) continue; |
| 467 |
3/5✓ Branch 30 → 31 taken 3 times.
✓ Branch 34 → 35 taken 9 times.
✓ Branch 34 → 36 taken 3 times.
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 57 not taken.
|
12 | result.append(QVariantMap{{"key", key}, {"name", row.name}, {"kind", contentKind(row)}}); |
| 468 | 36 | } | |
| 469 | 12 | return result; | |
| 470 | 15 | } | |
| 471 | |||
| 472 | 1 | QVariantMap DavCollectionDiscovery::addNew(const QString &key) { return toggleKey(key, true); } | |
| 473 | |||
| 474 | 4 | QVariantMap DavCollectionDiscovery::toggleKey(const QString &key, bool selected) { | |
| 475 |
2/2✓ Branch 11 → 3 taken 8 times.
✓ Branch 11 → 12 taken 1 time.
|
9 | for (int row = 0; row < m_rows.size(); ++row) |
| 476 |
3/3✓ Branch 4 → 5 taken 8 times.
✓ Branch 7 → 8 taken 3 times.
✓ Branch 7 → 9 taken 5 times.
|
8 | if (collectionKey(m_rows.at(row).path) == key) return toggle(row, selected); |
| 477 |
2/4✓ Branch 18 → 19 taken 1 time.
✓ Branch 18 → 20 taken 1 time.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 28 not taken.
|
4 | return {{QStringLiteral("ok"), false}}; |
| 478 | 3 | } | |
| 479 | |||
| 480 | ✗ | void DavCollectionDiscovery::dismissNew(const QString &key) { | |
| 481 | ✗ | rememberKnown({key}); | |
| 482 | ✗ | emit stateChanged(); | |
| 483 | ✗ | } | |
| 484 |