diff --git a/autotests/fakenetworkaccessmanager.cpp b/autotests/fakenetworkaccessmanager.cpp index e497212..2e62d4a 100644 --- a/autotests/fakenetworkaccessmanager.cpp +++ b/autotests/fakenetworkaccessmanager.cpp @@ -1,94 +1,94 @@ /* * Copyright (C) 2018 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "fakenetworkaccessmanager.h" #include "fakenetworkreply.h" #include "fakenetworkaccessmanagerfactory.h" #include "testutils.h" #include #include #include #include #include FakeNetworkAccessManager::FakeNetworkAccessManager(QObject *parent) : QNetworkAccessManager(parent) { } QNetworkReply *FakeNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &originalReq, QIODevice* outgoingData) { auto namFactory = dynamic_cast(KGAPI2::NetworkAccessManagerFactory::instance()); VERIFY2_RET(namFactory, "NAMFactory is nto a FakeNetworkAccessManagerFactory!", new FakeNetworkReply(op, originalReq)); VERIFY2_RET(namFactory->hasScenario(), "No scenario for request!", new FakeNetworkReply(op, originalReq)); const auto scenario = namFactory->nextScenario(); if (scenario.needsAuth) { VERIFY2_RET(originalReq.hasRawHeader("Authorization"), "Missing Auth token header!", new FakeNetworkReply(op, originalReq)); } COMPARE_RET(scenario.requestUrl, originalReq.url(), new FakeNetworkReply(op, originalReq)); if (op != QNetworkAccessManager::CustomOperation) { COMPARE_RET(scenario.requestMethod, op, new FakeNetworkReply(op, originalReq)); } else { const auto verb = originalReq.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray(); COMPARE_RET(verb, QByteArray("PUT"), new FakeNetworkReply(op, originalReq)); } - for (const auto requestHeader : qAsConst(scenario.requestHeaders)) { + for (const auto &requestHeader : qAsConst(scenario.requestHeaders)) { VERIFY2_RET(originalReq.hasRawHeader(requestHeader.first), qPrintable(QStringLiteral("Missing header '%1'").arg(QString::fromUtf8(requestHeader.first))), new FakeNetworkReply(op, originalReq)); COMPARE_RET(originalReq.rawHeader(requestHeader.first), requestHeader.second, new FakeNetworkReply(op, originalReq)); } if (outgoingData) { const auto actualRequest = outgoingData->readAll(); if (actualRequest.startsWith('<')) { const auto formattedInput = reformatXML(actualRequest); const auto formattedExpected = reformatXML(scenario.requestData); if (formattedInput != formattedExpected) { std::cerr << diffData(formattedInput, formattedExpected).constData() << std::endl; FAIL_RET("Request data don't match!", new FakeNetworkReply(op, originalReq)); } } else if (actualRequest.startsWith('{')) { const auto formattedInput = reformatJSON(actualRequest); const auto formattedExpected = reformatJSON(scenario.requestData); if (formattedInput != formattedExpected) { std::cerr << diffData(formattedInput, formattedExpected).constData() << std::endl; FAIL_RET("Request data don't match!", new FakeNetworkReply(op, originalReq)); } } else { COMPARE_RET(actualRequest, scenario.requestData, new FakeNetworkReply(op, originalReq)); } } return new FakeNetworkReply(scenario); } diff --git a/autotests/fakenetworkreply.cpp b/autotests/fakenetworkreply.cpp index 9f3afdd..01f4dcd 100644 --- a/autotests/fakenetworkreply.cpp +++ b/autotests/fakenetworkreply.cpp @@ -1,111 +1,111 @@ /* * Copyright (C) 2018 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "fakenetworkreply.h" #include "types.h" FakeNetworkReply::FakeNetworkReply(const FakeNetworkAccessManager::Scenario &scenario) : QNetworkReply() { setUrl(scenario.requestUrl); setOperation(scenario.requestMethod); setAttribute(QNetworkRequest::HttpStatusCodeAttribute, scenario.responseCode); setHeader(QNetworkRequest::ContentLengthHeader, scenario.responseData.size()); if (scenario.responseData.startsWith('<')) { setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/atom+xml")); } else if (scenario.responseData.startsWith('{')) { setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json")); } else { setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("text/plain")); } - for (const auto header : qAsConst(scenario.responseHeaders)) { + for (const auto &header : qAsConst(scenario.responseHeaders)) { setRawHeader(header.first, header.second); } if (scenario.responseCode == KGAPI2::TemporarilyMoved) { setHeader(QNetworkRequest::LocationHeader, QString::fromUtf8(scenario.responseData)); } else { mBuffer.setData(scenario.responseData); } mBuffer.open(QIODevice::ReadOnly); open(QIODevice::ReadOnly); setFinished(true); QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } FakeNetworkReply::FakeNetworkReply(QNetworkAccessManager::Operation method, const QNetworkRequest &originalRequest) : QNetworkReply() { setOperation(method); setUrl(originalRequest.url()); open(QIODevice::ReadOnly); setFinished(true); QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::UnknownServerError)); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } void FakeNetworkReply::abort() { // NOOP } bool FakeNetworkReply::atEnd() const { return mBuffer.atEnd(); } qint64 FakeNetworkReply::bytesAvailable() const { return mBuffer.bytesAvailable(); } bool FakeNetworkReply::canReadLine() const { return mBuffer.canReadLine(); } void FakeNetworkReply::close() { mBuffer.close(); } qint64 FakeNetworkReply::pos() const { return mBuffer.pos(); } qint64 FakeNetworkReply::size() const { return mBuffer.size(); } qint64 FakeNetworkReply::readData(char* data, qint64 maxLen) { return mBuffer.read(data, maxLen); } qint64 FakeNetworkReply::writeData(const char* data, qint64 len) { return mBuffer.write(data, len); } diff --git a/src/contacts/contactdeletejob.cpp b/src/contacts/contactdeletejob.cpp index 9c3c69f..2b373bf 100644 --- a/src/contacts/contactdeletejob.cpp +++ b/src/contacts/contactdeletejob.cpp @@ -1,126 +1,126 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "contactdeletejob.h" #include "contact.h" #include "contactsservice.h" #include "../debug.h" #include "utils.h" #include "account.h" #include "private/queuehelper_p.h" #include using namespace KGAPI2; class Q_DECL_HIDDEN ContactDeleteJob::Private { public: Private(ContactDeleteJob *parent); void processNextContact(); QueueHelper contactIds; private: ContactDeleteJob * const q; }; ContactDeleteJob::Private::Private(ContactDeleteJob* parent): q(parent) { } void ContactDeleteJob::Private::processNextContact() { if (contactIds.atEnd()) { q->emitFinished(); return; } const QString contactId = contactIds.current(); const QUrl url = ContactsService::removeContactUrl(q->account()->accountName(), contactId); QNetworkRequest request(url); request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setRawHeader("GData-Version", ContactsService::APIVersion().toLatin1()); QStringList headers; auto rawHeaderList = request.rawHeaderList(); headers.reserve(rawHeaderList.size()); for (const QByteArray &str : qAsConst(rawHeaderList)) { headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str)); } q->enqueueRequest(request); } ContactDeleteJob::ContactDeleteJob(const ContactsList& contacts, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private(this)) { d->contactIds.reserve(contacts.size()); for (const ContactPtr &contact : contacts) { d->contactIds << contact->uid(); } } ContactDeleteJob::ContactDeleteJob(const ContactPtr& contact, const AccountPtr& account, QObject* parent): DeleteJob(account, parent), d(new Private(this)) { d->contactIds << contact->uid(); } -ContactDeleteJob::ContactDeleteJob(const QStringList contactIds, const AccountPtr &account, QObject *parent): +ContactDeleteJob::ContactDeleteJob(const QStringList &contactIds, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private(this)) { d->contactIds = contactIds; } ContactDeleteJob::ContactDeleteJob(const QString &contactId, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private(this)) { d->contactIds << contactId; } ContactDeleteJob::~ContactDeleteJob() { delete d; } void ContactDeleteJob::start() { d->processNextContact(); } void ContactDeleteJob::handleReply(const QNetworkReply *reply, const QByteArray &rawData) { Q_UNUSED(reply) Q_UNUSED(rawData) d->contactIds.currentProcessed(); d->processNextContact(); } diff --git a/src/contacts/contactdeletejob.h b/src/contacts/contactdeletejob.h index f2275e3..b9fe2e3 100644 --- a/src/contacts/contactdeletejob.h +++ b/src/contacts/contactdeletejob.h @@ -1,120 +1,120 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef LIBKGAPI2_CONTACTDELETEJOB_H #define LIBKGAPI2_CONTACTDELETEJOB_H #include "deletejob.h" #include "kgapicontacts_export.h" namespace KGAPI2 { /** * @brief A job to delete one or more contacts from addressbook in * user's Google Contacts account * * Note that operation is irreversible. * * @author Daniel Vrátil * @since 2.0 */ class KGAPICONTACTS_EXPORT ContactDeleteJob : public KGAPI2::DeleteJob { Q_OBJECT public: /** * @brief Constructs a new job that will delete given @p contact from * user's addressbook * * @param contact Contact to delete * @param account Account to authenticate the request * @param parent */ explicit ContactDeleteJob(const ContactPtr &contact, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete given @p contacts from * user's addressbook * * @param contacts Contacts to delete * @param account Account to authenticate the request * @param parent */ explicit ContactDeleteJob(const ContactsList &contacts, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete contact with given * @p contactId from user's addressbook * * @param contactId ID of contact to delete * @param account Account to authenticate the request * @param parent */ explicit ContactDeleteJob(const QString &contactId, const AccountPtr &account, QObject* parent); /** * @brief Constructs a new job that will delete contacts with given * @p contactsIds from user's addressbook * * @param contactIds IDs of contacts to delete * @param account Account to authenticate the request * @param parent */ - explicit ContactDeleteJob(const QStringList contactIds, + explicit ContactDeleteJob(const QStringList &contactIds, const AccountPtr &account, QObject* parent); /** * @brief Destructor */ ~ContactDeleteJob() override; protected: /** * @brief KGAPI::Job::start implementation */ void start() override; /** * @brief KGAPI::Job::handleReply implementation * * @param reply * @param rawData */ void handleReply(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private * const d; friend class Private; }; } // namespace KGAPI2 #endif // LIBKGAPI2_CONTACTDELETEJOB_H