on xenial help sign in
better tests
f6cafe1Nick Dedekind
tests/plugins/AccountsService/AccountsServer.cpp+23−7
@@ -18,18 +18,34 @@
18 */
18 */
19
19
20#include "AccountsServer.h"
20#include "AccountsServer.h"
21+#include "PropertiesServer.h"
22+#include <QDBusConnection>
23+#include <QDebug>
21
24
22−AccountsServer::AccountsServer(QObject *parent)
25+AccountsServer::AccountsServer(PropertiesServer* propServer, QObject *parent)
23 : QObject(parent)
26 : QObject(parent)
27+ , m_propServer(propServer)
24{
28{
25}
29}
26
30
27QDBusObjectPath AccountsServer::FindUserByName(const QString &user)
31QDBusObjectPath AccountsServer::FindUserByName(const QString &user)
28{
32{
29− if (user == "testuser") {
33+ return QDBusObjectPath(QString("/%1").arg(user));
30− return QDBusObjectPath("/user");
34+}
31− } else {
35+
32− sendErrorReply(QDBusError::InvalidArgs, "Bad user");
36+bool AccountsServer::AddUser(const QString &user)
33− return QDBusObjectPath("/");
37+{
34− }
38+ QString path(QString("/%1").arg(user));
39+ if (QDBusConnection::sessionBus().objectRegisteredAt(path) == m_propServer)
40+ return true;
41+ return QDBusConnection::sessionBus().registerObject(path, m_propServer);
42+}
43+
44+bool AccountsServer::RemoveUser(const QString &user)
45+{
46+ QString path(QString("/%1").arg(user));
47+ if (QDBusConnection::sessionBus().objectRegisteredAt(path) != m_propServer)
48+ return false;
49+ QDBusConnection::sessionBus().unregisterObject(path);
50+ return true;
35}
51}
tests/plugins/AccountsService/AccountsServer.h+11−1
@@ -25,15 +25,25 @@
25#include <QObject>
25#include <QObject>
26#include <QString>
26#include <QString>
27
27
28+class PropertiesServer;
29+
28class AccountsServer: public QObject, protected QDBusContext
30class AccountsServer: public QObject, protected QDBusContext
29{
31{
30 Q_OBJECT
32 Q_OBJECT
31
33
32public:
34public:
33− explicit AccountsServer(QObject *parent = 0);
35+ explicit AccountsServer(PropertiesServer *propServer, QObject *parent = 0);
34
36
35public Q_SLOTS:
37public Q_SLOTS:
38+
36 QDBusObjectPath FindUserByName(const QString &user);
39 QDBusObjectPath FindUserByName(const QString &user);
40+
41+ // mock only.
42+ bool AddUser(const QString &user);
43+ bool RemoveUser(const QString &user);
44+
45+private:
46+ PropertiesServer* m_propServer;
37};
47};
38
48
39#endif
49#endif
tests/plugins/AccountsService/CMakeLists.txt+8
@@ -11,6 +11,10 @@ endmacro(make_dbus_class)
11
11
12make_dbus_class(Accounts org.freedesktop.Accounts)
12make_dbus_class(Accounts org.freedesktop.Accounts)
13make_dbus_class(Properties org.freedesktop.DBus.Properties)
13make_dbus_class(Properties org.freedesktop.DBus.Properties)
14+make_dbus_class(SecurityPrivacy com.ubuntu.touch.AccountsService.SecurityPrivacy)
15+make_dbus_class(Location com.ubuntu.location.providers.here.AccountsService)
16+make_dbus_class(AccountsUser org.freedesktop.Accounts.User)
17+make_dbus_class(AccountsPrivate com.canonical.unity.AccountsService.Private)
14
18
15include_directories(
19include_directories(
16 ${CMAKE_CURRENT_BINARY_DIR}
20 ${CMAKE_CURRENT_BINARY_DIR}
@@ -21,7 +25,11 @@ add_definitions(-DSM_BUSNAME=sessionBus)
21
25
22add_executable(mock-server
26add_executable(mock-server
23 ${CMAKE_CURRENT_BINARY_DIR}/AccountsAdaptor.cpp
27 ${CMAKE_CURRENT_BINARY_DIR}/AccountsAdaptor.cpp
28+ ${CMAKE_CURRENT_BINARY_DIR}/AccountsPrivateAdaptor.cpp
29+ ${CMAKE_CURRENT_BINARY_DIR}/AccountsUserAdaptor.cpp
24 ${CMAKE_CURRENT_BINARY_DIR}/PropertiesAdaptor.cpp
30 ${CMAKE_CURRENT_BINARY_DIR}/PropertiesAdaptor.cpp
31+ ${CMAKE_CURRENT_BINARY_DIR}/LocationAdaptor.cpp
32+ ${CMAKE_CURRENT_BINARY_DIR}/SecurityPrivacyAdaptor.cpp
25 server.cpp
33 server.cpp
26 AccountsServer.cpp
34 AccountsServer.cpp
27 PropertiesServer.cpp
35 PropertiesServer.cpp
tests/plugins/AccountsService/PropertiesServer.cpp+43−6
@@ -18,17 +18,22 @@
18 */
18 */
19
19
20#include "PropertiesServer.h"
20#include "PropertiesServer.h"
21+#include "AccountsService.h"
22+
23+// Qt
24+#include <QDebug>
25+#include <QDBusMessage>
21
26
22PropertiesServer::PropertiesServer(QObject *parent)
27PropertiesServer::PropertiesServer(QObject *parent)
23− : QObject(parent),
28+ : QObject(parent)
24− edge_demo(true)
25{
29{
30+ Reset();
26}
31}
27
32
28QDBusVariant PropertiesServer::Get(const QString &interface, const QString &property)
33QDBusVariant PropertiesServer::Get(const QString &interface, const QString &property)
29{
34{
30− if (interface == "com.canonical.unity.AccountsService" && property == "demo-edges") {
35+ if (m_properties[interface].contains(property)) {
31− return QDBusVariant(QVariant(edge_demo));
36+ return QDBusVariant(m_properties[interface][property]);
32 } else {
37 } else {
33 sendErrorReply(QDBusError::InvalidArgs, "Bad interface or property");
38 sendErrorReply(QDBusError::InvalidArgs, "Bad interface or property");
34 return QDBusVariant(QVariant());
39 return QDBusVariant(QVariant());
@@ -37,9 +42,41 @@ QDBusVariant PropertiesServer::Get(const QString &interface, const QString &prop
37
42
38void PropertiesServer::Set(const QString &interface, const QString &property, const QDBusVariant &variant)
43void PropertiesServer::Set(const QString &interface, const QString &property, const QDBusVariant &variant)
39{
44{
40− if (interface == "com.canonical.unity.AccountsService" && property == "demo-edges") {
45+ QVariant newValue = variant.variant();
41− edge_demo = variant.variant().toBool();
46+
47+ if (m_properties[interface].contains(property)) {
48+ QVariant& oldValue = m_properties[interface][property];
49+ if (oldValue != newValue) {
50+ oldValue = newValue;
51+
52+ // Special case for Background file.
53+ if (interface == "org.freedesktop.Accounts.User" && property == "BackgroundFile") {
54+ Q_EMIT Changed();
55+ } else {
56+ QVariantMap propertyChanges;
57+ propertyChanges[property] = newValue;
58+ Q_EMIT PropertiesChanged(interface, propertyChanges, QStringList());
59+
60+ // FIXME: Here to replicate current behaviour
61+ // Not sure why accounts-service is triggering Changed when we're
62+ // emitting PropertyChanges from org.freedesktop.DBus.Properties as well.
63+ Q_EMIT Changed();
64+ }
65+ }
42 } else {
66 } else {
43 sendErrorReply(QDBusError::InvalidArgs, "Bad interface or property");
67 sendErrorReply(QDBusError::InvalidArgs, "Bad interface or property");
44 }
68 }
45}
69}
70+
71+void PropertiesServer::Reset()
72+{
73+ m_properties["com.canonical.unity.AccountsService"]["demo-edges"] = false;
74+ m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
75+ m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
76+ m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableLauncherWhileLocked"] = true;
77+ m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["EnableIndicatorsWhileLocked"] = true;
78+ m_properties["com.ubuntu.AccountsService.SecurityPrivacy"]["PasswordDisplayHint"] = AccountsService::Keyboard;
79+ m_properties["com.ubuntu.location.providers.here.AccountsService"]["LicenseAccepted"] = false;
80+ m_properties["com.ubuntu.location.providers.here.AccountsService"]["LicenseBasePath"] = "";
81+ m_properties["org.freedesktop.Accounts.User"]["BackgroundFile"] = "";
82+}
tests/plugins/AccountsService/PropertiesServer.h+8−1
@@ -37,8 +37,15 @@ public Q_SLOTS:
37 QDBusVariant Get(const QString &interface, const QString &property);
37 QDBusVariant Get(const QString &interface, const QString &property);
38 void Set(const QString &interface, const QString &property, const QDBusVariant &variant);
38 void Set(const QString &interface, const QString &property, const QDBusVariant &variant);
39
39
40+ // mock only.
41+ void Reset();
42+
43+Q_SIGNALS:
44+ void PropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
45+ void Changed();
46+
40private:
47private:
41− bool edge_demo;
48+ QHash<QString, QVariantMap> m_properties;
42};
49};
43
50
44#endif
51#endif
tests/plugins/AccountsService/client.cpp+166−7
@@ -21,39 +21,198 @@
21#include "AccountsServiceDBusAdaptor.h"
21#include "AccountsServiceDBusAdaptor.h"
22#include <QSignalSpy>
22#include <QSignalSpy>
23#include <QTest>
23#include <QTest>
24+#include <QDebug>
25+#include <QDBusReply>
26+
27+template <class T>
28+QVariant dbusVariant(const T& value) { return QVariant::fromValue(QDBusVariant(value)); }
29+
30+#define ASSERT_DBUS_CALL(call) \
31+ { \
32+ QDBusReply<void> reply = call; \
33+ if (!reply.isValid()) QFAIL(reply.error().message().toLatin1()); \
34+ }
24
35
25class AccountsServiceTest : public QObject
36class AccountsServiceTest : public QObject
26{
37{
27 Q_OBJECT
38 Q_OBJECT
28
39
40+public:
41+ AccountsServiceTest(QObject* parent = 0)
42+ : QObject(parent)
43+ , m_userInterface(nullptr)
44+ , m_spy(this, &AccountsServiceTest::propertiesChanged)
45+ {
46+ }
47+
29private Q_SLOTS:
48private Q_SLOTS:
30
49
50+ void init() {
51+ QDBusReply<bool> addReply = QDBusInterface("org.freedesktop.Accounts",
52+ "/org/freedesktop/Accounts",
53+ "org.freedesktop.Accounts").call("AddUser", QTest::currentTestFunction());
54+ QVERIFY(addReply.isValid());
55+ QCOMPARE(addReply.value(), true);
56+
57+ m_userInterface = new QDBusInterface("org.freedesktop.Accounts",
58+ QString("/%1").arg(QTest::currentTestFunction()),
59+ "org.freedesktop.DBus.Properties", QDBusConnection::sessionBus(), this);
60+ QDBusReply<void> resetReply = m_userInterface->call("Reset");
61+ QVERIFY(resetReply.isValid());
62+
63+ QVERIFY(QObject::connect(m_userInterface, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)),
64+ this, SIGNAL(propertiesChanged(QString, QVariantMap, QStringList))));
65+ }
66+
67+ void cleanup() {
68+ QDBusReply<bool> reply = QDBusInterface("org.freedesktop.Accounts",
69+ "/org/freedesktop/Accounts",
70+ "org.freedesktop.Accounts").call("RemoveUser", QTest::currentTestFunction());
71+ QVERIFY(reply.isValid());
72+ QCOMPARE(reply.value(), true);
73+
74+ delete m_userInterface;
75+ m_spy.clear();
76+ }
77+
31 void testInvalids()
78 void testInvalids()
32 {
79 {
33 // Test various invalid calls
80 // Test various invalid calls
34 AccountsServiceDBusAdaptor session;
81 AccountsServiceDBusAdaptor session;
35 QCOMPARE(session.getUserProperty("NOPE", "com.canonical.unity.AccountsService", "demo-edges"), QVariant());
82 QCOMPARE(session.getUserProperty("NOPE", "com.canonical.unity.AccountsService", "demo-edges"), QVariant());
36− QCOMPARE(session.getUserProperty("testuser", "com.canonical.unity.AccountsService", "NOPE"), QVariant());
83+ QCOMPARE(session.getUserProperty(QTest::currentTestFunction(), "com.canonical.unity.AccountsService", "NOPE"), QVariant());
37 }
84 }
38
85
39 void testGetSetServiceDBusAdaptor()
86 void testGetSetServiceDBusAdaptor()
40 {
87 {
41 AccountsServiceDBusAdaptor session;
88 AccountsServiceDBusAdaptor session;
42− session.setUserProperty("testuser", "com.canonical.unity.AccountsService", "demo-edges", QVariant(true));
89+ session.setUserProperty(QTest::currentTestFunction(), "com.canonical.unity.AccountsService", "demo-edges", QVariant(true));
43− QCOMPARE(session.getUserProperty("testuser", "com.canonical.unity.AccountsService", "demo-edges"), QVariant(true));
90+ QCOMPARE(session.getUserProperty(QTest::currentTestFunction(), "com.canonical.unity.AccountsService", "demo-edges"), QVariant(true));
44− session.setUserProperty("testuser", "com.canonical.unity.AccountsService", "demo-edges", QVariant(false));
91+ session.setUserProperty(QTest::currentTestFunction(), "com.canonical.unity.AccountsService", "demo-edges", QVariant(false));
45− QCOMPARE(session.getUserProperty("testuser", "com.canonical.unity.AccountsService", "demo-edges"), QVariant(false));
92+ QCOMPARE(session.getUserProperty(QTest::currentTestFunction(), "com.canonical.unity.AccountsService", "demo-edges"), QVariant(false));
46 }
93 }
47
94
48 void testGetSetService()
95 void testGetSetService()
49 {
96 {
50 AccountsService session;
97 AccountsService session;
51− session.setUser("testuser");
98+ session.setUser(QTest::currentTestFunction());
99+
100+ QCOMPARE(session.demoEdges(), false);
52 session.setDemoEdges(true);
101 session.setDemoEdges(true);
53 QCOMPARE(session.demoEdges(), true);
102 QCOMPARE(session.demoEdges(), true);
103+
104+ QCOMPARE(session.failedLogins(), (uint)0);
105+ session.setFailedLogins(5);
106+ QCOMPARE(session.failedLogins(), (uint)5);
107+
54− session.setDemoEdges(false);
108+ QCOMPARE(session.hereEnabled(), false);
109+ session.setHereEnabled(true);
110+ QCOMPARE(session.hereEnabled(), true);
111+ }
112+
113+ void testAsynchornousChangeForDemoEdges()
114+ {
115+ AccountsService session;
116+ session.setUser(QTest::currentTestFunction());
117+
55 QCOMPARE(session.demoEdges(), false);
118 QCOMPARE(session.demoEdges(), false);
119+ ASSERT_DBUS_CALL(m_userInterface->call("Set", "com.canonical.unity.AccountsService", "demo-edges", dbusVariant(true)));
120+ QTRY_COMPARE(session.demoEdges(), true);
121+ }
122+
123+ void testAsynchornousChangeForFailedLogins()
124+ {
125+ AccountsService session;
126+ session.setUser(QTest::currentTestFunction());
127+
128+ QCOMPARE(session.failedLogins(), (uint)0);
129+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.canonical.unity.AccountsService.Private", "FailedLogins", dbusVariant(5)));
130+ QTRY_COMPARE(session.failedLogins(), (uint)5);
131+ }
132+
133+ void testAsynchornousChangeForStatsWelcomeScreen()
134+ {
135+ AccountsService session;
136+ session.setUser(QTest::currentTestFunction());
137+
138+ QCOMPARE(session.statsWelcomeScreen(), true);
139+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.touch.AccountsService.SecurityPrivacy", "StatsWelcomeScreen", dbusVariant(false)));
140+ QTRY_COMPARE(session.statsWelcomeScreen(), false);
56 }
141 }
142+
143+ void testAsynchornousChangeForStatsEnableLauncherWhileLocked()
144+ {
145+ AccountsService session;
146+ session.setUser(QTest::currentTestFunction());
147+
148+ QCOMPARE(session.enableLauncherWhileLocked(), true);
149+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.AccountsService.SecurityPrivacy", "EnableLauncherWhileLocked", dbusVariant(false)));
150+ QTRY_COMPARE(session.enableLauncherWhileLocked(), false);
151+ }
152+
153+ void testAsynchornousChangeForStatsEnableIndicatorsWhileLocked()
154+ {
155+ AccountsService session;
156+ session.setUser(QTest::currentTestFunction());
157+
158+ QCOMPARE(session.enableIndicatorsWhileLocked(), true);
159+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.AccountsService.SecurityPrivacy", "EnableIndicatorsWhileLocked", dbusVariant(false)));
160+ QTRY_COMPARE(session.enableIndicatorsWhileLocked(), false);
161+ }
162+
163+ void testAsynchornousChangeForStatsPasswordDisplayHint()
164+ {
165+ AccountsService session;
166+ session.setUser(QTest::currentTestFunction());
167+
168+ QCOMPARE(session.passwordDisplayHint(), AccountsService::Keyboard);
169+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.AccountsService.SecurityPrivacy", "PasswordDisplayHint", dbusVariant(AccountsService::Numeric)));
170+ QTRY_COMPARE(session.passwordDisplayHint(), AccountsService::Numeric);
171+ }
172+
173+ void testAsynchornousChangeForStatsLicenseAccepted()
174+ {
175+ AccountsService session;
176+ session.setUser(QTest::currentTestFunction());
177+
178+ QCOMPARE(session.hereEnabled(), false);
179+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.location.providers.here.AccountsService", "LicenseAccepted", dbusVariant(true)));
180+ QTRY_COMPARE(session.hereEnabled(), true);
181+ }
182+
183+ void testAsynchornousChangeForLicenseBasePath()
184+ {
185+ AccountsService session;
186+ session.setUser(QTest::currentTestFunction());
187+
188+ QCOMPARE(session.hereLicensePath(), QString());
189+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "com.ubuntu.location.providers.here.AccountsService", "LicenseBasePath", dbusVariant("/")));
190+ QTRY_COMPARE(session.hereLicensePath(), QString("/"));
191+ }
192+
193+ void testAsynchornousChangeForStatsBackgroundFile()
194+ {
195+ AccountsService session;
196+ session.setUser(QTest::currentTestFunction());
197+
198+ QCOMPARE(session.backgroundFile(), QString());
199+ ASSERT_DBUS_CALL(m_userInterface->asyncCall("Set", "org.freedesktop.Accounts.User", "BackgroundFile", dbusVariant("/test/BackgroundFile")));
200+ QTRY_COMPARE(session.backgroundFile(), QString("/test/BackgroundFile"));
201+ }
202+
203+Q_SIGNALS:
204+ void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
205+
206+//public Q_SLOTS:
207+// void propertiesChangedSlot(const QString &interface, const QVariantMap &changed, const QStringList &invalid) {
208+// QDBusInterface* pInterface = qobject_cast<QDBusInterface*>(sender());
209+// qDebug() << "propertiesChangedSlot" << pInterface->path() << QTest::currentTestFunction() << changed;
210+// Q_EMIT propertiesChanged(interface, changed, invalid);
211+// }
212+
213+private:
214+ QDBusInterface* m_userInterface;
215+ QSignalSpy m_spy;
57};
216};
58
217
59QTEST_MAIN(AccountsServiceTest)
218QTEST_MAIN(AccountsServiceTest)
tests/plugins/AccountsService/interfaces.xml+21
@@ -10,11 +10,32 @@
10 <arg name="property" type="s" direction="in" />
10 <arg name="property" type="s" direction="in" />
11 <arg name="value" type="v" direction="in" />
11 <arg name="value" type="v" direction="in" />
12 </method>
12 </method>
13+ <method name="Reset" />
14+ <signal name="PropertiesChanged">
15+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
16+ <arg name="interface" type="s" direction="out" />
17+ <arg name="changed" type="a{sv}" direction="out" />
18+ <arg name="invalid" type="as" direction="out" />
19+ </signal>
13 </interface>
20 </interface>
14 <interface name="org.freedesktop.Accounts">
21 <interface name="org.freedesktop.Accounts">
15 <method name="FindUserByName">
22 <method name="FindUserByName">
16 <arg name="user" type="s" direction="in" />
23 <arg name="user" type="s" direction="in" />
17 <arg name="path" type="o" direction="out" />
24 <arg name="path" type="o" direction="out" />
18 </method>
25 </method>
26+ <method name="AddUser">
27+ <arg name="user" type="s" direction="in" />
28+ <arg name="success" type="b" direction="out" />
29+ </method>
30+ <method name="RemoveUser">
31+ <arg name="user" type="s" direction="in" />
32+ <arg name="success" type="b" direction="out" />
33+ </method>
34+ </interface>
35+ <interface name="com.ubuntu.touch.AccountsService.SecurityPrivacy" />
36+ <interface name="com.ubuntu.location.providers.here.AccountsService" />
37+ <interface name="org.freedesktop.Accounts.User">
38+ <signal name="Changed" />
19 </interface>
39 </interface>
40+ <interface name="com.canonical.unity.AccountsService.Private" />
20</node>
41</node>
tests/plugins/AccountsService/server.cpp+11−6
@@ -21,24 +21,29 @@
21#include "AccountsServer.h"
21#include "AccountsServer.h"
22#include "PropertiesAdaptor.h"
22#include "PropertiesAdaptor.h"
23#include "PropertiesServer.h"
23#include "PropertiesServer.h"
24+#include "SecurityPrivacyAdaptor.h"
25+#include "LocationAdaptor.h"
26+#include "AccountsUserAdaptor.h"
27+#include "AccountsPrivateAdaptor.h"
24#include <QCoreApplication>
28#include <QCoreApplication>
25
29
26int main(int argc, char *argv[])
30int main(int argc, char *argv[])
27{
31{
28 QCoreApplication a(argc, argv);
32 QCoreApplication a(argc, argv);
29
33
30− auto accounts = new AccountsServer();
31− new AccountsAdaptor(accounts);
32−
33− auto props = new PropertiesServer();
34+ auto props = new PropertiesServer(&a);
34 new PropertiesAdaptor(props);
35 new PropertiesAdaptor(props);
36+ new AccountsUserAdaptor(props);
35
37
38+ auto accounts = new AccountsServer(props, &a);
39+ new AccountsAdaptor(accounts);
40+ new SecurityPrivacyAdaptor(accounts);
41+ new LocationAdaptor(accounts);
42+ new AccountsPrivateAdaptor(accounts);
36 // We use the session bus for testing. The real plugin uses the system bus
43 // We use the session bus for testing. The real plugin uses the system bus
37 auto connection = QDBusConnection::sessionBus();
44 auto connection = QDBusConnection::sessionBus();
38 if (!connection.registerObject("/org/freedesktop/Accounts", accounts))
45 if (!connection.registerObject("/org/freedesktop/Accounts", accounts))
39 return 1;
46 return 1;
40− if (!connection.registerObject("/user", props))
41− return 1;
42 if (!connection.registerService("org.freedesktop.Accounts"))
47 if (!connection.registerService("org.freedesktop.Accounts"))
43 return 1;
48 return 1;
44
49