Add a test for file sending, using the loopback device

Extends unit testing by making sure that file sharing works locally.

REVIEW: 125086
This commit is contained in:
Aleix Pol 2015-09-07 14:54:33 +02:00
parent d41eab2fae
commit d835d01a09
11 changed files with 150 additions and 11 deletions

View file

@ -46,6 +46,8 @@ bool LoopbackDeviceLink::sendPackageEncrypted(QCA::PublicKey& key, NetworkPackag
//LoopbackDeviceLink does not need deviceTransferInfo //LoopbackDeviceLink does not need deviceTransferInfo
if (input.hasPayload()) { if (input.hasPayload()) {
bool b = input.payload()->open(QIODevice::ReadOnly);
Q_ASSERT(b);
output.setPayload(input.payload(), input.payloadSize()); output.setPayload(input.payload(), input.payloadSize());
} }
@ -61,6 +63,8 @@ bool LoopbackDeviceLink::sendPackage(NetworkPackage& input)
//LoopbackDeviceLink does not need deviceTransferInfo //LoopbackDeviceLink does not need deviceTransferInfo
if (input.hasPayload()) { if (input.hasPayload()) {
bool b = input.payload()->open(QIODevice::ReadOnly);
Q_ASSERT(b);
output.setPayload(input.payload(), input.payloadSize()); output.setPayload(input.payload(), input.payloadSize());
} }

View file

@ -52,7 +52,7 @@ Daemon* Daemon::instance()
return *s_instance; return *s_instance;
} }
Daemon::Daemon(QObject *parent) Daemon::Daemon(QObject *parent, bool testMode)
: QObject(parent) : QObject(parent)
, d(new DaemonPrivate) , d(new DaemonPrivate)
{ {
@ -61,8 +61,10 @@ Daemon::Daemon(QObject *parent)
qCDebug(KDECONNECT_CORE) << "KdeConnect daemon starting"; qCDebug(KDECONNECT_CORE) << "KdeConnect daemon starting";
//Load backends //Load backends
if (testMode)
d->mLinkProviders.insert(new LoopbackLinkProvider());
else
d->mLinkProviders.insert(new LanLinkProvider()); d->mLinkProviders.insert(new LanLinkProvider());
//d->mLinkProviders.insert(new LoopbackLinkProvider());
//Read remebered paired devices //Read remebered paired devices
const QStringList& list = KdeConnectConfig::instance()->trustedDevices(); const QStringList& list = KdeConnectConfig::instance()->trustedDevices();
@ -106,12 +108,12 @@ void Daemon::forceOnNetworkChange()
} }
} }
QStringList Daemon::devices(bool onlyReachable, bool onlyVisible) const QStringList Daemon::devices(bool onlyReachable, bool onlyPaired) const
{ {
QStringList ret; QStringList ret;
Q_FOREACH(Device* device, d->mDevices) { Q_FOREACH(Device* device, d->mDevices) {
if (onlyReachable && !device->isReachable()) continue; if (onlyReachable && !device->isReachable()) continue;
if (onlyVisible && !device->isPaired()) continue; if (onlyPaired && !device->isPaired()) continue;
ret.append(device->id()); ret.append(device->id());
} }
return ret; return ret;
@ -182,6 +184,11 @@ QNetworkAccessManager* Daemon::networkAccessManager()
return manager; return manager;
} }
QList<Device*> Daemon::devicesList() const
{
return d->mDevices.values();
}
Daemon::~Daemon() Daemon::~Daemon()
{ {

View file

@ -39,7 +39,7 @@ class KDECONNECTCORE_EXPORT Daemon
Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon") Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon")
public: public:
explicit Daemon(QObject *parent); explicit Daemon(QObject *parent, bool testMode = false);
~Daemon(); ~Daemon();
public Q_SLOTS: public Q_SLOTS:
@ -55,16 +55,18 @@ public Q_SLOTS:
Q_SCRIPTABLE void forceOnNetworkChange(); Q_SCRIPTABLE void forceOnNetworkChange();
Q_SCRIPTABLE QString announcedName(); QString announcedName();
Q_SCRIPTABLE void setAnnouncedName(QString name); void setAnnouncedName(QString name);
//Returns a list of ids. The respective devices can be manipulated using the dbus path: "/modules/kdeconnect/Devices/"+id //Returns a list of ids. The respective devices can be manipulated using the dbus path: "/modules/kdeconnect/Devices/"+id
Q_SCRIPTABLE QStringList devices(bool onlyReachable = false, bool onlyVisible = false) const; Q_SCRIPTABLE QStringList devices(bool onlyReachable = false, bool onlyPaired = false) const;
virtual void requestPairing(Device *d) = 0; virtual void requestPairing(Device *d) = 0;
virtual void reportError(const QString &title, const QString &description) = 0; virtual void reportError(const QString &title, const QString &description) = 0;
virtual QNetworkAccessManager* networkAccessManager(); virtual QNetworkAccessManager* networkAccessManager();
QList<Device*> devicesList() const;
Q_SIGNALS: Q_SIGNALS:
Q_SCRIPTABLE void deviceAdded(const QString& id); Q_SCRIPTABLE void deviceAdded(const QString& id);
Q_SCRIPTABLE void deviceRemoved(const QString& id); //Note that paired devices will never be removed Q_SCRIPTABLE void deviceRemoved(const QString& id); //Note that paired devices will never be removed

View file

@ -522,3 +522,8 @@ void Device::setName(const QString &name)
Q_EMIT nameChanged(name); Q_EMIT nameChanged(name);
} }
} }
KdeConnectPlugin* Device::plugin(const QString& pluginName) const
{
return m_plugins[pluginName];
}

View file

@ -102,6 +102,8 @@ public:
Q_SCRIPTABLE QString pluginsConfigFile() const; Q_SCRIPTABLE QString pluginsConfigFile() const;
KdeConnectPlugin* plugin(const QString& plugin) const;
public Q_SLOTS: public Q_SLOTS:
///sends a @p np package to the device ///sends a @p np package to the device
virtual bool sendPackage(NetworkPackage& np); virtual bool sendPackage(NetworkPackage& np);

View file

@ -39,6 +39,7 @@ FileTransferJob::FileTransferJob(const QSharedPointer<QIODevice>& origin, qint64
, mWritten(0) , mWritten(0)
{ {
Q_ASSERT(mOrigin); Q_ASSERT(mOrigin);
Q_ASSERT(mOrigin->isReadable());
if (mDestination.scheme().isEmpty()) { if (mDestination.scheme().isEmpty()) {
qWarning() << "Destination QUrl" << mDestination << "lacks a scheme. Setting its scheme to 'file'."; qWarning() << "Destination QUrl" << mDestination << "lacks a scheme. Setting its scheme to 'file'.";
mDestination.setScheme("file"); mDestination.setScheme("file");

View file

@ -33,13 +33,15 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QBuffer> #include <QBuffer>
#include "kdeconnectcore_export.h"
/** /**
* @short It will stream a device into a url destination * @short It will stream a device into a url destination
* *
* Given a QIODevice, the file transfer job will use the system's QNetworkAccessManager * Given a QIODevice, the file transfer job will use the system's QNetworkAccessManager
* for putting the stream into the requested location. * for putting the stream into the requested location.
*/ */
class FileTransferJob class KDECONNECTCORE_EXPORT FileTransferJob
: public KJob : public KJob
{ {
Q_OBJECT Q_OBJECT

View file

@ -129,7 +129,11 @@ bool SharePlugin::receivePackage(const NetworkPackage& np)
void SharePlugin::finished(KJob* job) void SharePlugin::finished(KJob* job)
{ {
qCDebug(KDECONNECT_PLUGIN_SHARE) << "File transfer finished. Success:" << (!job->error()); FileTransferJob* ftjob = qobject_cast<FileTransferJob*>(job);
if (ftjob)
fileReceived(ftjob->destination());
qCDebug(KDECONNECT_PLUGIN_SHARE) << "File transfer finished. Success:" << (!job->error()) << (ftjob ? ftjob->destination() : QUrl());
} }
void SharePlugin::openDestinationFolder() void SharePlugin::openDestinationFolder()

View file

@ -47,6 +47,9 @@ private Q_SLOTS:
void finished(KJob*); void finished(KJob*);
void openDestinationFolder(); void openDestinationFolder();
Q_SIGNALS:
void fileReceived(const QUrl& url);
private: private:
void shareUrl(const QUrl& url); void shareUrl(const QUrl& url);

View file

@ -13,5 +13,6 @@ set(kdeconnect_libraries
qca-qt5 qca-qt5
) )
ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
ecm_add_test(networkpackagetests.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(networkpackagetests.cpp LINK_LIBRARIES ${kdeconnect_libraries})
ecm_add_test(testsocketlinereader.cpp ../core/backends/lan/socketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(testsocketlinereader.cpp ../core/backends/lan/socketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries})

108
tests/sendfiletest.cpp Normal file
View file

@ -0,0 +1,108 @@
/**
* Copyright 2015 Aleix Pol Gonzalez <aleixpol@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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 14 of version 3 of the license.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QSocketNotifier>
#include <QApplication>
#include <QNetworkAccessManager>
#include <QTest>
#include <QTemporaryFile>
#include <QSignalSpy>
#include <KIO/AccessManager>
#include "core/daemon.h"
#include "core/device.h"
#include "core/kdeconnectplugin.h"
#include "kdeconnect-version.h"
class TestDaemon : public Daemon
{
Q_OBJECT
public:
TestDaemon(QObject* parent = Q_NULLPTR)
: Daemon(parent, true)
, m_nam(Q_NULLPTR)
{
}
void requestPairing(Device* d) Q_DECL_OVERRIDE
{
d->acceptPairing();
}
void reportError(const QString & title, const QString & description) Q_DECL_OVERRIDE
{
qWarning() << "error:" << title << description;
}
QNetworkAccessManager* networkAccessManager() Q_DECL_OVERRIDE
{
if (!m_nam) {
m_nam = new KIO::AccessManager(this);
}
return m_nam;
}
private:
QNetworkAccessManager* m_nam;
};
class TestSendFile : public QObject
{
Q_OBJECT
public:
TestSendFile() : mDaemon(new TestDaemon) {}
private Q_SLOTS:
void testSend() {
Device* d = mDaemon->devicesList().first();
QCOMPARE(d->isReachable(), true);
QCOMPARE(d->isPaired(), true);
QByteArray content("12312312312313213123213123");
QTemporaryFile temp;
temp.open();
temp.write(content);
temp.close();
KdeConnectPlugin* plugin = d->plugin("kdeconnect_share");
QVERIFY(plugin);
plugin->metaObject()->invokeMethod(plugin, "shareUrl", Q_ARG(QString, QUrl::fromLocalFile(temp.fileName()).toString()));
QSignalSpy spy(plugin, SIGNAL(fileReceived(QUrl)));
QVERIFY(spy.wait(2000));
QVariantList args = spy.takeFirst();
QUrl sentFile = args.first().toUrl();
QFile file(sentFile.toLocalFile());
QCOMPARE(file.size(), content.size());
QVERIFY(file.open(QIODevice::ReadOnly));
QCOMPARE(file.readAll(), content);
}
private:
TestDaemon* mDaemon;
};
QTEST_MAIN(TestSendFile);
#include "sendfiletest.moc"