service/DavPushServiceTest.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "DavPushServiceTest.h" | ||
| 2 | #include "AuthenticatedRequest.h" | ||
| 3 | |||
| 4 | #include "NtfyPushReceiver.h" | ||
| 5 | #include "WebPushPayloadCodec.h" | ||
| 6 | |||
| 7 | #include <QLoggingCategory> | ||
| 8 | #include <QNetworkAccessManager> | ||
| 9 | #include <QNetworkReply> | ||
| 10 | #include <QNetworkRequest> | ||
| 11 | #include <QRandomGenerator> | ||
| 12 | #include <QUrl> | ||
| 13 | |||
| 14 |
4/7✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 8 taken 2 times.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
3 | Q_LOGGING_CATEGORY(lcDavPushTest, "mailjd.davpush.servicetest") |
| 15 | |||
| 16 |
1/1✓ Branch 5 → 6 taken 4 times.
|
4 | DavPushServiceTest::DavPushServiceTest(QObject *parent) : QObject(parent) { |
| 17 |
3/6✓ Branch 11 → 12 taken 4 times.
✓ Branch 12 → 13 taken 4 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 4 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
|
4 | m_nam = new QNetworkAccessManager(this); |
| 18 |
1/1✓ Branch 15 → 16 taken 4 times.
|
4 | m_timeout.setSingleShot(true); |
| 19 |
1/1✓ Branch 16 → 17 taken 4 times.
|
4 | m_timeout.setInterval(15000); |
| 20 |
1/1✓ Branch 17 → 18 taken 4 times.
|
4 | connect(&m_timeout, &QTimer::timeout, this, [this] { |
| 21 | ✗ | finish(m_published ? Result::NoDelivery : Result::Timeout); | |
| 22 | ✗ | }); | |
| 23 | 4 | } | |
| 24 | |||
| 25 | 5 | DavPushServiceTest::~DavPushServiceTest() { | |
| 26 | 4 | cancel(); | |
| 27 | 5 | } | |
| 28 | |||
| 29 | 1 | void DavPushServiceTest::setNetworkAccessManager(QNetworkAccessManager *nam) { | |
| 30 |
4/8✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 6 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 10 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
|
1 | if (m_nam && m_nam->parent() == this) delete m_nam; |
| 31 | 1 | m_nam = nam; | |
| 32 |
1/2✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 12 not taken.
|
1 | if (m_nam) m_nam->setParent(this); |
| 33 | 1 | } | |
| 34 | |||
| 35 | 4 | void DavPushServiceTest::start(const QString &server, const QByteArray &token) { | |
| 36 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 4 times.
|
5 | if (m_running) return; |
| 37 |
1/1✓ Branch 4 → 5 taken 4 times.
|
4 | const QUrl url(server); |
| 38 |
12/19✓ Branch 5 → 6 taken 4 times.
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 15 not taken.
✓ Branch 8 → 9 taken 4 times.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 15 taken 1 time.
✓ Branch 12 → 13 taken 3 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 3 times.
✓ Branch 17 → 18 taken 3 times.
✓ Branch 17 → 19 taken 1 time.
✓ Branch 19 → 20 taken 4 times.
✗ Branch 19 → 21 not taken.
✓ Branch 21 → 22 taken 1 time.
✓ Branch 21 → 26 taken 3 times.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 89 not taken.
✗ Branch 92 → 93 not taken.
✗ Branch 92 → 94 not taken.
|
7 | if (!url.isValid() || url.scheme() != QLatin1String("https") || url.host().isEmpty()) { |
| 39 |
1/1✓ Branch 23 → 24 taken 1 time.
|
1 | emit finished(Result::InvalidUrl, {}); |
| 40 | 1 | return; | |
| 41 | } | ||
| 42 | 3 | m_running = true; | |
| 43 | 3 | m_published = false; | |
| 44 | 3 | m_server = server; | |
| 45 | 3 | m_token = token; | |
| 46 |
1/1✓ Branch 28 → 29 taken 3 times.
|
3 | QByteArray random(16, Qt::Uninitialized); |
| 47 |
4/5✓ Branch 29 → 30 taken 3 times.
✗ Branch 29 → 128 not taken.
✓ Branch 30 → 31 taken 3 times.
✓ Branch 31 → 32 taken 3 times.
✓ Branch 32 → 33 taken 3 times.
|
3 | QRandomGenerator::system()->generate(random.begin(), random.end()); |
| 48 | // Same topic form as real receivers (servers with subscriber-based rate | ||
| 49 | // limiting refuse other UnifiedPush names). | ||
| 50 | static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
| 51 | 3 | m_channel = QStringLiteral("up"); | |
| 52 |
5/6✓ Branch 40 → 41 taken 36 times.
✗ Branch 40 → 100 not taken.
✓ Branch 41 → 42 taken 36 times.
✓ Branch 44 → 45 taken 36 times.
✓ Branch 46 → 40 taken 36 times.
✓ Branch 46 → 47 taken 3 times.
|
39 | for (int i = 0; i < 12; ++i) m_channel.append(QLatin1Char(alphabet[QRandomGenerator::system()->bounded(62)])); |
| 53 |
2/2✓ Branch 47 → 48 taken 3 times.
✓ Branch 48 → 49 taken 3 times.
|
3 | m_probe = "mailjd-test-" + random.toHex(); |
| 54 |
9/14✓ Branch 53 → 54 taken 2 times.
✓ Branch 53 → 56 taken 1 time.
✓ Branch 54 → 55 taken 2 times.
✓ Branch 56 → 57 taken 1 time.
✓ Branch 57 → 58 taken 1 time.
✓ Branch 59 → 60 taken 3 times.
✓ Branch 60 → 61 taken 1 time.
✓ Branch 60 → 63 taken 2 times.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 63 taken 1 time.
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 109 not taken.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
|
3 | m_receiver = m_receiverFactory ? m_receiverFactory(this) : new NtfyPushReceiver(this); |
| 55 |
1/1✓ Branch 64 → 65 taken 3 times.
|
3 | connect(m_receiver, &PushReceiver::stateChanged, this, [this] { |
| 56 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 6 times.
|
6 | if (!m_receiver) return; |
| 57 | 6 | const auto failure = m_receiver->failure(); | |
| 58 |
1/3✗ Branch 7 → 8 not taken.
✓ Branch 7 → 13 taken 6 times.
✗ Branch 10 → 11 not taken.
|
6 | if (failure == PushReceiver::Failure::Tls) finish(Result::Tls, m_receiver->failureDetail()); |
| 59 |
3/3✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 19 taken 5 times.
✓ Branch 16 → 17 taken 1 time.
|
6 | else if (failure == PushReceiver::Failure::Authentication) finish(Result::Authentication, m_receiver->failureDetail()); |
| 60 |
3/4✓ Branch 19 → 20 taken 4 times.
✓ Branch 19 → 21 taken 1 time.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 26 taken 4 times.
|
5 | else if (failure == PushReceiver::Failure::Network || failure == PushReceiver::Failure::Protocol) |
| 61 |
1/1✓ Branch 23 → 24 taken 1 time.
|
1 | finish(Result::Unreachable, m_receiver->failureDetail()); |
| 62 | }); | ||
| 63 |
1/1✓ Branch 67 → 68 taken 3 times.
|
3 | connect(m_receiver, &PushReceiver::streamResumed, this, &DavPushServiceTest::publish); |
| 64 |
1/1✓ Branch 70 → 71 taken 3 times.
|
3 | connect(m_receiver, &PushReceiver::messageReceived, this, [this](const QByteArray &payload) { |
| 65 |
2/3✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 8 not taken.
✓ Branch 5 → 6 taken 1 time.
|
1 | if (payload == m_probe) finish(Result::Ok); |
| 66 | 1 | }); | |
| 67 |
1/1✓ Branch 72 → 73 taken 3 times.
|
3 | m_timeout.start(); |
| 68 | 6 | m_receiver->start({server, m_channel, token, {}}); | |
| 69 | 7 | } | |
| 70 | |||
| 71 | 1 | void DavPushServiceTest::publish() { | |
| 72 |
2/4✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
|
1 | if (m_published || !m_running) return; |
| 73 | 1 | m_published = true; | |
| 74 |
4/4✓ Branch 7 → 8 taken 1 time.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 10 → 11 taken 1 time.
|
1 | QNetworkRequest request(QUrl(m_server + QLatin1Char('/') + m_channel)); |
| 75 |
3/3✓ Branch 14 → 15 taken 1 time.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 16 → 17 taken 1 time.
|
1 | request.setRawHeader("Content-Type", "text/plain"); |
| 76 |
1/1✓ Branch 25 → 26 taken 1 time.
|
3 | m_publishRequest = AuthenticatedRequest::start(this, m_nam, request, |
| 77 |
2/3✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
|
2 | m_token.isEmpty() ? QByteArray() : "Bearer " + m_token, m_probe, true, |
| 78 | AuthenticatedRequest::ForeignRedirect::Refuse, | ||
| 79 | 1 | [this](AuthenticatedRequest::Result result) { | |
| 80 | ✗ | m_publishRequest = nullptr; | |
| 81 | ✗ | if (!m_running) return; | |
| 82 | ✗ | if (result.outcome == AuthenticatedRequest::Outcome::Unauthorized) | |
| 83 | ✗ | finish(Result::Authentication, QStringLiteral("publishing was refused")); | |
| 84 | ✗ | else if (result.outcome == AuthenticatedRequest::Outcome::RedirectedToForeignHost) | |
| 85 | ✗ | finish(Result::Unreachable, tr("The push server redirected to another host (%1).").arg(result.url.host())); | |
| 86 | ✗ | else if (result.outcome != AuthenticatedRequest::Outcome::Ok) | |
| 87 | ✗ | finish(Result::Unreachable, QStringLiteral("publishing failed")); | |
| 88 |
2/2✓ Branch 26 → 27 taken 1 time.
✓ Branch 27 → 28 taken 1 time.
|
1 | }); |
| 89 | 1 | } | |
| 90 | |||
| 91 | 3 | void DavPushServiceTest::finish(Result result, const QString &detail) { | |
| 92 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 3 times.
|
3 | if (!m_running) return; |
| 93 | 3 | m_running = false; | |
| 94 | 3 | m_timeout.stop(); | |
| 95 |
2/2✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 12 taken 2 times.
|
3 | if (m_publishRequest) { |
| 96 | 1 | m_publishRequest->cancel(); | |
| 97 | 1 | m_publishRequest->deleteLater(); | |
| 98 | 1 | m_publishRequest = nullptr; | |
| 99 | } | ||
| 100 | 3 | m_token.clear(); | |
| 101 |
1/2✓ Branch 14 → 15 taken 3 times.
✗ Branch 14 → 22 not taken.
|
3 | if (m_receiver) { |
| 102 | 3 | m_receiver->disconnect(this); | |
| 103 | 3 | m_receiver->stop(); | |
| 104 | 3 | m_receiver->deleteLater(); | |
| 105 | 3 | m_receiver = nullptr; | |
| 106 | } | ||
| 107 |
7/7✓ Branch 22 → 23 taken 3 times.
✓ Branch 26 → 27 taken 3 times.
✓ Branch 27 → 28 taken 3 times.
✓ Branch 29 → 30 taken 3 times.
✓ Branch 30 → 31 taken 3 times.
✓ Branch 36 → 24 taken 3 times.
✓ Branch 36 → 37 taken 3 times.
|
6 | qCInfo(lcDavPushTest) << "Push service test:" << result << detail; |
| 108 | 3 | emit finished(result, detail); | |
| 109 | } | ||
| 110 | |||
| 111 | 4 | void DavPushServiceTest::cancel() { | |
| 112 |
1/2✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 4 not taken.
|
4 | if (!m_running) return; |
| 113 | ✗ | m_running = false; | |
| 114 | ✗ | m_timeout.stop(); | |
| 115 | ✗ | if (m_publishRequest) { | |
| 116 | ✗ | m_publishRequest->cancel(); | |
| 117 | ✗ | m_publishRequest->deleteLater(); | |
| 118 | ✗ | m_publishRequest = nullptr; | |
| 119 | } | ||
| 120 | ✗ | m_token.clear(); | |
| 121 | ✗ | if (m_receiver) { | |
| 122 | ✗ | m_receiver->disconnect(this); | |
| 123 | ✗ | m_receiver->stop(); | |
| 124 | ✗ | m_receiver->deleteLater(); | |
| 125 | ✗ | m_receiver = nullptr; | |
| 126 | } | ||
| 127 | } | ||
| 128 |