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:
parent
d41eab2fae
commit
d835d01a09
11 changed files with 150 additions and 11 deletions
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
108
tests/sendfiletest.cpp
Normal 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"
|
Loading…
Reference in a new issue