Merge lp:~online-accounts/ubuntu-system-settings-online-accounts/master into lp:ubuntu-system-settings-online-accounts

Proposed by Alberto Mardegan on 2015-02-18
Status: Merged
Approved by: David Barth on 2015-03-20
Approved revision: 234
Merged at revision: 242
Proposed branch: lp:~online-accounts/ubuntu-system-settings-online-accounts/master
Merge into: lp:ubuntu-system-settings-online-accounts
Diff against target: 1002 lines (+687/-31)
19 files modified
.bzrignore (+1/-0)
click-hooks/main.cpp (+28/-6)
debian/changelog (+10/-0)
online-accounts-service/mir-helper-stub.cpp (+9/-0)
online-accounts-service/mir-helper.h (+2/-0)
online-accounts-service/ui-proxy.cpp (+14/-16)
online-accounts-ui/browser-request.cpp (+2/-0)
online-accounts-ui/signonui-request.cpp (+9/-0)
system-settings-plugin/online-accounts.settings (+2/-6)
system-settings-plugin/plugin.cpp (+116/-0)
system-settings-plugin/plugin.h (+36/-0)
system-settings-plugin/system-settings-plugin.pro (+24/-1)
tests/click-hooks/click-hooks.pro (+5/-1)
tests/click-hooks/tst_online_accounts_hooks.cpp (+63/-0)
tests/online-accounts-service/tst_ui_proxy.cpp (+39/-0)
tests/online-accounts-service/tst_ui_proxy.pro (+1/-0)
tests/system-settings-plugin/system-settings-plugin.pro (+32/-0)
tests/system-settings-plugin/tst_plugin.cpp (+292/-0)
tests/tests.pro (+2/-1)
To merge this branch: bzr merge lp:~online-accounts/ubuntu-system-settings-online-accounts/master
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve on 2015-02-23
Online Accounts 2015-02-18 Pending
Review via email: mp+250095@code.launchpad.net

Commit message

Merge from upstream

- Add account data as search keywords (LP: #1373279)
- Delete accounts when their plugin is removed (LP: #1413542)
- More fixes for plugin confinement (LP: #1219644)
- Fail initialization if trust session cannot be setup (LP: #1420847)

Description of the change

Merge from upstream

- Add account data as search keywords (LP: #1373279)
- Delete accounts when their plugin is removed (LP: #1413542)
- More fixes for plugin confinement (LP: #1219644)
- Fail initialization if trust session cannot be setup (LP: #1420847)

To post a comment you must log in.
232. By Alberto Mardegan on 2015-02-18

From trunk

[ CI Train Bot ]
* Fix tests with Qt 5.4
[ Timo Jyrinki ]
* Use qt_gl_set_global_share_context with Qt 5.4 (LP: #1398372) (LP:
  #1398372)

233. By Alberto Mardegan on 2015-02-18

fix version

234. By Alberto Mardegan on 2015-02-23

Disconnect from signal

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2014-12-11 12:51:46 +0000
3+++ .bzrignore 2015-02-23 09:45:54 +0000
4@@ -57,3 +57,4 @@
5 /tests/online-accounts-ui/tst_notification
6 /tests/online-accounts-ui/tst_signonui_request
7 /tests/plugin/tst_application_manager
8+/tests/system-settings-plugin/tst_plugin
9
10=== modified file 'click-hooks/main.cpp'
11--- click-hooks/main.cpp 2015-01-21 15:11:36 +0000
12+++ click-hooks/main.cpp 2015-02-23 09:45:54 +0000
13@@ -217,7 +217,20 @@
14 }
15 }
16
17-static void removeStaleFiles(const QStringList &fileTypes,
18+static void removeStaleAccounts(Accounts::Manager *manager,
19+ const QString &providerName)
20+{
21+ Q_FOREACH(Accounts::AccountId id, manager->accountList()) {
22+ Accounts::Account *account = manager->account(id);
23+ if (account->providerName() == providerName) {
24+ account->remove();
25+ account->syncAndBlock();
26+ }
27+ }
28+}
29+
30+static void removeStaleFiles(Accounts::Manager *manager,
31+ const QStringList &fileTypes,
32 const QString &localShare,
33 const QDir &hooksDirIn)
34 {
35@@ -245,8 +258,13 @@
36 * means that the click package was removed, and we must remove our
37 * copy as well. */
38 QString hookFileName = profile + "." + fileType;
39- if (!hooksDirIn.exists(hookFileName)) {
40- QFile::remove(fileInfo.filePath());
41+ if (hooksDirIn.exists(hookFileName)) continue;
42+
43+ QFile::remove(fileInfo.filePath());
44+ /* If this is a provider, we must also remove any accounts
45+ * associated with it */
46+ if (fileType == QStringLiteral("provider")) {
47+ removeStaleAccounts(manager, fileInfo.completeBaseName());
48 }
49 }
50 }
51@@ -256,6 +274,12 @@
52 {
53 QCoreApplication app(argc, argv);
54
55+ Accounts::Manager::Options managerOptions;
56+ if (qgetenv("DBUS_SESSION_BUS_ADDRESS").isEmpty()) {
57+ managerOptions |= Accounts::Manager::DisableNotifications;
58+ }
59+ Accounts::Manager *manager = new Accounts::Manager(managerOptions);
60+
61 /* Go through the hook files in ~/.local/share/online-accounts-hooks/ and
62 * check if they have already been processed into a file under
63 * ~/.local/share/accounts/{providers,services,service-types,applications}/;
64@@ -274,7 +298,7 @@
65 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
66 QDir hooksDirIn(localShare + "/" HOOK_FILES_SUBDIR);
67
68- removeStaleFiles(fileTypes, localShare, hooksDirIn);
69+ removeStaleFiles(manager, fileTypes, localShare, hooksDirIn);
70
71 Q_FOREACH(const QFileInfo &fileInfo, hooksDirIn.entryInfoList()) {
72 const QString fileType = fileInfo.suffix();
73@@ -320,8 +344,6 @@
74 /* To ensure that all the installed services are parsed into
75 * libaccounts' DB, we enumerate them now.
76 */
77- Accounts::Manager *manager =
78- new Accounts::Manager(Accounts::Manager::DisableNotifications);
79 manager->serviceList();
80 delete manager;
81
82
83=== modified file 'debian/changelog'
84--- debian/changelog 2015-02-11 06:39:10 +0000
85+++ debian/changelog 2015-02-23 09:45:54 +0000
86@@ -1,3 +1,13 @@
87+ubuntu-system-settings-online-accounts (0.6+15.04.20150211-0ubuntu2) UNRELEASED; urgency=medium
88+
89+ * Merge from upstream
90+ - Add account data as search keywords (LP: #1373279)
91+ - Delete accounts when their plugin is removed (LP: #1413542)
92+ - More fixes for plugin confinement (LP: #1219644)
93+ - Fail initialization if trust session cannot be setup (LP: #1420847)
94+
95+ -- Alberto Mardegan <alberto.mardegan@canonical.com> Wed, 18 Feb 2015 09:34:01 +0200
96+
97 ubuntu-system-settings-online-accounts (0.6+15.04.20150211-0ubuntu1) vivid; urgency=medium
98
99 [ CI Train Bot ]
100
101=== modified file 'online-accounts-service/mir-helper-stub.cpp'
102--- online-accounts-service/mir-helper-stub.cpp 2014-11-25 13:34:16 +0000
103+++ online-accounts-service/mir-helper-stub.cpp 2015-02-23 09:45:54 +0000
104@@ -40,7 +40,11 @@
105
106 QString PromptSession::requestSocket()
107 {
108+#ifdef BUILDING_TESTS
109+ return QString::fromUtf8(qgetenv("TEST_MIR_HELPER_SOCKET"));
110+#else
111 return QString();
112+#endif
113 }
114
115 MirHelper::MirHelper(QObject *parent):
116@@ -65,5 +69,10 @@
117 PromptSessionP MirHelper::createPromptSession(pid_t initiatorPid)
118 {
119 Q_UNUSED(initiatorPid);
120+#ifdef BUILDING_TESTS
121+ return qgetenv("TEST_MIR_HELPER_FAIL_CREATE").isEmpty() ?
122+ PromptSessionP(new PromptSession(0)) : PromptSessionP();
123+#else
124 return PromptSessionP();
125+#endif
126 }
127
128=== modified file 'online-accounts-service/mir-helper.h'
129--- online-accounts-service/mir-helper.h 2014-11-21 13:50:15 +0000
130+++ online-accounts-service/mir-helper.h 2015-02-23 09:45:54 +0000
131@@ -27,6 +27,7 @@
132 namespace OnlineAccountsUi {
133
134 class PromptSessionPrivate;
135+class MirHelper;
136 class MirHelperPrivate;
137
138 class PromptSession: public QObject
139@@ -45,6 +46,7 @@
140 explicit PromptSession(PromptSessionPrivate *priv);
141
142 private:
143+ friend class MirHelper;
144 friend class MirHelperPrivate;
145 PromptSessionPrivate *d_ptr;
146 Q_DECLARE_PRIVATE(PromptSession)
147
148=== modified file 'online-accounts-service/ui-proxy.cpp'
149--- online-accounts-service/ui-proxy.cpp 2015-02-03 10:21:46 +0000
150+++ online-accounts-service/ui-proxy.cpp 2015-02-23 09:45:54 +0000
151@@ -225,6 +225,8 @@
152 {
153 Q_Q(UiProxy);
154
155+ if (!m_clientPid) return false;
156+
157 PromptSessionP session =
158 MirHelper::instance()->createPromptSession(m_clientPid);
159 if (!session) return false;
160@@ -246,15 +248,20 @@
161
162 bool UiProxyPrivate::init()
163 {
164- m_arguments.clear();
165- if (!m_promptSession) {
166- /* the first argument is required to be the desktop file */
167- m_arguments.append("--desktop_file_hint=/usr/share/applications/online-accounts-ui.desktop");
168+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
169+ if (env.value("QT_QPA_PLATFORM").startsWith("ubuntu")) {
170+ if (!setupPromptSession()) {
171+ qWarning() << "Couldn't setup prompt session";
172+ return false;
173+ }
174 }
175
176- if (m_clientPid) {
177- setupPromptSession();
178- }
179+ /* We also create ~/cache/online-accounts-ui/, since the plugin might not
180+ * have permissions to do that. */
181+ QString userCacheDir =
182+ QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
183+ QDir cacheDir(userCacheDir + "/online-accounts-ui");
184+ if (!cacheDir.exists()) cacheDir.mkpath(".");
185
186 return true;
187 }
188@@ -313,15 +320,6 @@
189 m_arguments.prepend(accountsUi);
190 }
191
192- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
193- if (env.value("QT_QPA_PLATFORM").startsWith("ubuntu")) {
194- if (!setupPromptSession()) {
195- qWarning() << "Couldn't setup prompt session";
196- setStatus(UiProxy::Error);
197- return;
198- }
199- }
200-
201 setStatus(UiProxy::Loading);
202 m_process.start(processName, m_arguments);
203 if (Q_UNLIKELY(!m_process.waitForStarted())) {
204
205=== modified file 'online-accounts-ui/browser-request.cpp'
206--- online-accounts-ui/browser-request.cpp 2015-01-09 10:12:03 +0000
207+++ online-accounts-ui/browser-request.cpp 2015-02-23 09:45:54 +0000
208@@ -265,6 +265,8 @@
209 Q_Q(BrowserRequest);
210
211 DEBUG() << "Browser dialog closed";
212+ QObject::disconnect(m_dialog, SIGNAL(finished(int)),
213+ this, SLOT(onFinished()));
214
215 QVariantMap reply;
216 QUrl url = m_responseUrl.isEmpty() ? m_currentUrl : m_responseUrl;
217
218=== modified file 'online-accounts-ui/signonui-request.cpp'
219--- online-accounts-ui/signonui-request.cpp 2015-01-14 09:31:14 +0000
220+++ online-accounts-ui/signonui-request.cpp 2015-02-23 09:45:54 +0000
221@@ -33,6 +33,8 @@
222 #include <SignOn/uisessiondata.h>
223 #include <SignOn/uisessiondata_priv.h>
224 #include <sys/apparmor.h>
225+#include <sys/types.h>
226+#include <unistd.h>
227
228 using namespace SignOnUi;
229
230@@ -135,6 +137,13 @@
231 if (profile == "unconfined" &&
232 parameters.contains(SSOUI_KEY_PID)) {
233 pid_t pid = parameters.value(SSOUI_KEY_PID).toUInt();
234+ if (pid == getpid()) {
235+ /* If the request was initiated by our own process, we might not
236+ * have the rights to call the aa_* functions (we might be
237+ * confined). */
238+ return QString();
239+ }
240+
241 char *con = NULL, *mode = NULL;
242 int ret = aa_gettaskcon(pid, &con, &mode);
243 if (Q_LIKELY(ret >= 0)) {
244
245=== modified file 'system-settings-plugin/online-accounts.settings'
246--- system-settings-plugin/online-accounts.settings 2014-09-24 19:05:32 +0000
247+++ system-settings-plugin/online-accounts.settings 2015-02-23 09:45:54 +0000
248@@ -14,14 +14,10 @@
249 "access",
250 "authorize",
251 "revoke",
252- "web",
253- "facebook",
254- "twitter",
255- "flickr",
256- "google",
257- "gmail"
258+ "web"
259 ],
260 "has-dynamic-keywords": true,
261 "has-dynamic-visibility": false,
262+ "plugin": "online-accounts",
263 "page-component": "MainPage.qml"
264 }
265
266=== added file 'system-settings-plugin/plugin.cpp'
267--- system-settings-plugin/plugin.cpp 1970-01-01 00:00:00 +0000
268+++ system-settings-plugin/plugin.cpp 2015-02-23 09:45:54 +0000
269@@ -0,0 +1,116 @@
270+/*
271+ * Copyright (C) 2015 Canonical Ltd.
272+ *
273+ * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
274+ *
275+ * This program is free software: you can redistribute it and/or modify it
276+ * under the terms of the GNU General Public License version 3, as published
277+ * by the Free Software Foundation.
278+ *
279+ * This program is distributed in the hope that it will be useful, but
280+ * WITHOUT ANY WARRANTY; without even the implied warranties of
281+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
282+ * PURPOSE. See the GNU General Public License for more details.
283+ *
284+ * You should have received a copy of the GNU General Public License along
285+ * with this program. If not, see <http://www.gnu.org/licenses/>.
286+ */
287+
288+#include "plugin.h"
289+
290+#include <Accounts/Account>
291+#include <Accounts/Manager>
292+#include <Accounts/Provider>
293+#include <Accounts/Service>
294+#include <QDebug>
295+#include <QStringList>
296+#include <SystemSettings/ItemBase>
297+#include <libintl.h>
298+
299+using namespace SystemSettings;
300+
301+class Item: public ItemBase
302+{
303+ Q_OBJECT
304+
305+public:
306+ Item(const QVariantMap &staticData, QObject *parent = 0);
307+ ~Item();
308+
309+private:
310+ void computeKeywords();
311+};
312+
313+Item::Item(const QVariantMap &staticData, QObject *parent):
314+ ItemBase(staticData, parent)
315+{
316+ computeKeywords();
317+}
318+
319+Item::~Item()
320+{
321+}
322+
323+static QStringList translations(const QString &text, const QString &domain)
324+{
325+ /* Return a list of keywords based on a translatable name:
326+ * - the untranslated text (lowercase, split into words)
327+ * - the translated text (lowercase, split into words)
328+ */
329+ QStringList keys;
330+ keys = text.toLower().split(" ", QString::SkipEmptyParts);
331+ if (!domain.isEmpty()) {
332+ QByteArray baText = text.toUtf8();
333+ QByteArray baDomain = domain.toUtf8();
334+ QString translated = QString::fromUtf8(dgettext(baDomain.constData(),
335+ baText.constData()));
336+ if (translated != text) {
337+ keys.append(translated.toLower().split(" ",
338+ QString::SkipEmptyParts));
339+ }
340+ }
341+ return keys;
342+}
343+
344+void Item::computeKeywords()
345+{
346+ Accounts::Manager *manager = new Accounts::Manager;
347+
348+ QStringList keywords;
349+
350+ /* List available providers, and add their names to the search keywords */
351+ Q_FOREACH(const Accounts::Provider &provider, manager->providerList()) {
352+ keywords.append(provider.name().toLower());
353+ keywords.append(translations(provider.displayName(),
354+ provider.trCatalog()));
355+ }
356+
357+ /* Same for services */
358+ Q_FOREACH(const Accounts::Service &service, manager->serviceList()) {
359+ keywords.append(service.name().toLower());
360+ keywords.append(translations(service.displayName(),
361+ service.trCatalog()));
362+ }
363+
364+ /* Also add the account display names */
365+ Q_FOREACH(Accounts::AccountId id, manager->accountList()) {
366+ Accounts::Account *account = manager->account(id);
367+ if (Q_UNLIKELY(!account)) continue;
368+ QString name = account->displayName().toLower();
369+ if (!name.isEmpty()) {
370+ keywords.append(name);
371+ }
372+ }
373+
374+ delete manager;
375+
376+ setKeywords(keywords);
377+}
378+
379+ItemBase *Plugin::createItem(const QVariantMap &staticData,
380+ QObject *parent)
381+{
382+ return new Item(staticData, parent);
383+}
384+
385+#include "plugin.moc"
386
387=== added file 'system-settings-plugin/plugin.h'
388--- system-settings-plugin/plugin.h 1970-01-01 00:00:00 +0000
389+++ system-settings-plugin/plugin.h 2015-02-23 09:45:54 +0000
390@@ -0,0 +1,36 @@
391+/*
392+ * Copyright (C) 2015 Canonical Ltd.
393+ *
394+ * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
395+ *
396+ * This program is free software: you can redistribute it and/or modify it
397+ * under the terms of the GNU General Public License version 3, as published
398+ * by the Free Software Foundation.
399+ *
400+ * This program is distributed in the hope that it will be useful, but
401+ * WITHOUT ANY WARRANTY; without even the implied warranties of
402+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
403+ * PURPOSE. See the GNU General Public License for more details.
404+ *
405+ * You should have received a copy of the GNU General Public License along
406+ * with this program. If not, see <http://www.gnu.org/licenses/>.
407+ */
408+
409+#ifndef ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
410+#define ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
411+
412+#include <QObject>
413+#include <SystemSettings/PluginInterface>
414+
415+class Plugin: public QObject, public SystemSettings::PluginInterface2
416+{
417+ Q_OBJECT
418+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
419+ Q_INTERFACES(SystemSettings::PluginInterface2)
420+
421+public:
422+ SystemSettings::ItemBase *createItem(const QVariantMap &staticData,
423+ QObject *parent = 0);
424+};
425+
426+#endif // ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
427
428=== modified file 'system-settings-plugin/system-settings-plugin.pro'
429--- system-settings-plugin/system-settings-plugin.pro 2014-08-13 13:11:06 +0000
430+++ system-settings-plugin/system-settings-plugin.pro 2015-02-23 09:45:54 +0000
431@@ -1,7 +1,27 @@
432 include(../common-project-config.pri)
433 include($${TOP_SRC_DIR}/common-vars.pri)
434
435-TEMPLATE=aux
436+TEMPLATE=lib
437+TARGET = online-accounts
438+
439+CONFIG += \
440+ link_pkgconfig \
441+ plugin \
442+ qt
443+
444+QT += \
445+ core \
446+ qml
447+
448+PKGCONFIG += \
449+ SystemSettings \
450+ accounts-qt5
451+
452+SOURCES += \
453+ plugin.cpp
454+
455+HEADERS += \
456+ plugin.h
457
458 QML_SOURCES = \
459 AccountEditPage.qml \
460@@ -19,6 +39,9 @@
461 settings.path = $${PLUGIN_MANIFEST_DIR}
462 INSTALLS += settings
463
464+target.path = $${PLUGIN_MODULE_DIR}
465+INSTALLS += target
466+
467 image.files = settings-accounts.svg
468 image.path = $${PLUGIN_MANIFEST_DIR}/icons
469 INSTALLS += image
470
471=== modified file 'tests/click-hooks/click-hooks.pro'
472--- tests/click-hooks/click-hooks.pro 2014-05-16 09:42:06 +0000
473+++ tests/click-hooks/click-hooks.pro 2015-02-23 09:45:54 +0000
474@@ -3,13 +3,17 @@
475 TARGET = tst_online_accounts_hooks
476
477 CONFIG += \
478- debug
479+ debug \
480+ link_pkgconfig
481
482 QT += \
483 core \
484 testlib \
485 xml
486
487+PKGCONFIG += \
488+ accounts-qt5
489+
490 DEFINES += \
491 DEBUG_ENABLED \
492 HOOK_PROCESS=\\\"../../click-hooks/online-accounts-hooks\\\"
493
494=== modified file 'tests/click-hooks/tst_online_accounts_hooks.cpp'
495--- tests/click-hooks/tst_online_accounts_hooks.cpp 2014-11-04 12:26:46 +0000
496+++ tests/click-hooks/tst_online_accounts_hooks.cpp 2015-02-23 09:45:54 +0000
497@@ -18,6 +18,8 @@
498 * with this program. If not, see <http://www.gnu.org/licenses/>.
499 */
500
501+#include <Accounts/Account>
502+#include <Accounts/Manager>
503 #include <QDebug>
504 #include <QDir>
505 #include <QDomDocument>
506@@ -42,6 +44,7 @@
507 void testValidHooks_data();
508 void testValidHooks();
509 void testRemoval();
510+ void testAccountRemoval();
511 void testUpdate();
512 void testDesktopEntry_data();
513 void testDesktopEntry();
514@@ -139,6 +142,8 @@
515 {
516 qputenv("XDG_DATA_HOME", TEST_DIR);
517 qputenv("OAH_CLICK_DIR", m_packageDir.path().toUtf8());
518+ qputenv("ACCOUNTS", TEST_DIR);
519+
520 // The hook must be able to run without a D-Bus session
521 qunsetenv("DBUS_SESSION_BUS_ADDRESS");
522
523@@ -377,6 +382,64 @@
524 QVERIFY(m_installDir.exists(noProfile));
525 }
526
527+void OnlineAccountsHooksTest::testAccountRemoval()
528+{
529+ clearHooksDir();
530+ clearInstallDir();
531+
532+ Accounts::Manager *manager =
533+ new Accounts::Manager(Accounts::Manager::DisableNotifications);
534+
535+ QString stillInstalled("providers/com.ubuntu.test_StillInstalled.provider");
536+ writeInstalledFile(stillInstalled,
537+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
538+ "<provider>\n"
539+ " <profile>com-ubuntu.test_StillInstalled_2.0</profile>\n"
540+ "</provider>");
541+ QVERIFY(m_installDir.exists(stillInstalled));
542+
543+ writeHookFile("com-ubuntu.test_StillInstalled_2.0.provider",
544+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
545+ "<provider>\n"
546+ "</provider>");
547+
548+ Accounts::Account *account =
549+ manager->createAccount("com.ubuntu.test_StillInstalled");
550+ account->setDisplayName("Still alive");
551+ account->syncAndBlock();
552+ Accounts::AccountId idPreserved = account->id();
553+ QVERIFY(idPreserved > 0);
554+
555+ QString myProvider("providers/com.ubuntu.test_MyProvider.provider");
556+ writeInstalledFile(myProvider,
557+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
558+ "<provider>\n"
559+ " <profile>com-ubuntu.test_MyProvider_3.0</profile>\n"
560+ "</provider>");
561+ QVERIFY(m_installDir.exists(myProvider));
562+
563+ account = manager->createAccount("com.ubuntu.test_MyProvider");
564+ account->setDisplayName("Must die");
565+ account->syncAndBlock();
566+ Accounts::AccountId idRemoved = account->id();
567+ QVERIFY(idRemoved > 0);
568+
569+ delete manager;
570+
571+ QVERIFY(runHookProcess());
572+
573+ QVERIFY(m_installDir.exists(stillInstalled));
574+ QVERIFY(!m_installDir.exists(myProvider));
575+
576+ manager = new Accounts::Manager(Accounts::Manager::DisableNotifications);
577+ account = manager->account(idPreserved);
578+ QVERIFY(account != 0);
579+ account = manager->account(idRemoved);
580+ QVERIFY(account == 0);
581+
582+ delete manager;
583+}
584+
585 void OnlineAccountsHooksTest::testUpdate()
586 {
587 clearHooksDir();
588
589=== modified file 'tests/online-accounts-service/tst_ui_proxy.cpp'
590--- tests/online-accounts-service/tst_ui_proxy.cpp 2014-12-03 13:42:09 +0000
591+++ tests/online-accounts-service/tst_ui_proxy.cpp 2015-02-23 09:45:54 +0000
592@@ -204,6 +204,8 @@
593 void testRequestDelay();
594 void testHandler();
595 void testWrapper();
596+ void testTrustSessionError_data();
597+ void testTrustSessionError();
598
599 private:
600 QDBusConnection m_connection;
601@@ -477,6 +479,43 @@
602 delete proxy;
603 }
604
605+void UiProxyTest::testTrustSessionError_data()
606+{
607+ QTest::addColumn<int>("clientPid");
608+ QTest::addColumn<QString>("envVar");
609+ QTest::addColumn<bool>("expectSuccess");
610+
611+ QTest::newRow("PID 0") << 0 << "" << false;
612+
613+ QTest::newRow("fail creation") << 4 <<
614+ "TEST_MIR_HELPER_FAIL_CREATE=1" << false;
615+
616+ QTest::newRow("return empty socket") << 4 <<
617+ "" << false;
618+
619+ QTest::newRow("success") << 4 <<
620+ "TEST_MIR_HELPER_SOCKET=something" << true;
621+}
622+
623+void UiProxyTest::testTrustSessionError()
624+{
625+ QFETCH(int, clientPid);
626+ QFETCH(QString, envVar);
627+ QFETCH(bool, expectSuccess);
628+
629+ qputenv("QT_QPA_PLATFORM", "ubuntu-something");
630+
631+ QStringList envVarSplit = envVar.split('=');
632+ QByteArray envVarKey = envVarSplit.value(0, "").toUtf8();
633+ QByteArray envVarValue = envVarSplit.value(1, "").toUtf8();
634+ qputenv(envVarKey.constData(), envVarValue);
635+ UiProxy *proxy = new UiProxy(clientPid, this);
636+ QCOMPARE(proxy->init(), expectSuccess);
637+ delete proxy;
638+
639+ qunsetenv(envVarKey.constData());
640+}
641+
642 QTEST_MAIN(UiProxyTest);
643
644 #include "tst_ui_proxy.moc"
645
646=== modified file 'tests/online-accounts-service/tst_ui_proxy.pro'
647--- tests/online-accounts-service/tst_ui_proxy.pro 2014-12-08 16:22:39 +0000
648+++ tests/online-accounts-service/tst_ui_proxy.pro 2015-02-23 09:45:54 +0000
649@@ -13,6 +13,7 @@
650 testlib
651
652 DEFINES += \
653+ BUILDING_TESTS \
654 INSTALL_BIN_DIR=\\\"$${INSTALL_PREFIX}/bin\\\"
655
656 PKGCONFIG += \
657
658=== added directory 'tests/system-settings-plugin'
659=== added file 'tests/system-settings-plugin/system-settings-plugin.pro'
660--- tests/system-settings-plugin/system-settings-plugin.pro 1970-01-01 00:00:00 +0000
661+++ tests/system-settings-plugin/system-settings-plugin.pro 2015-02-23 09:45:54 +0000
662@@ -0,0 +1,32 @@
663+include(../../common-project-config.pri)
664+
665+TARGET = tst_plugin
666+
667+CONFIG += \
668+ debug \
669+ link_pkgconfig
670+
671+QT += \
672+ core \
673+ qml \
674+ testlib
675+
676+PKGCONFIG += \
677+ SystemSettings \
678+ accounts-qt5
679+
680+SYSTEM_SETTINGS_PLUGIN_DIR = $${TOP_SRC_DIR}/system-settings-plugin
681+
682+INCLUDEPATH += \
683+ $${SYSTEM_SETTINGS_PLUGIN_DIR}
684+
685+SOURCES += \
686+ $${SYSTEM_SETTINGS_PLUGIN_DIR}/plugin.cpp \
687+ tst_plugin.cpp
688+
689+HEADERS += \
690+ $${SYSTEM_SETTINGS_PLUGIN_DIR}/plugin.h
691+
692+check.commands = "xvfb-run -s '-screen 0 640x480x24' -a dbus-test-runner -t ./$${TARGET}"
693+check.depends = $${TARGET}
694+QMAKE_EXTRA_TARGETS += check
695
696=== added file 'tests/system-settings-plugin/tst_plugin.cpp'
697--- tests/system-settings-plugin/tst_plugin.cpp 1970-01-01 00:00:00 +0000
698+++ tests/system-settings-plugin/tst_plugin.cpp 2015-02-23 09:45:54 +0000
699@@ -0,0 +1,292 @@
700+/*
701+ * Copyright (C) 2014 Canonical Ltd.
702+ *
703+ * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
704+ *
705+ * This file is part of online-accounts-ui
706+ *
707+ * This program is free software: you can redistribute it and/or modify it
708+ * under the terms of the GNU General Public License version 3, as published
709+ * by the Free Software Foundation.
710+ *
711+ * This program is distributed in the hope that it will be useful, but
712+ * WITHOUT ANY WARRANTY; without even the implied warranties of
713+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
714+ * PURPOSE. See the GNU General Public License for more details.
715+ *
716+ * You should have received a copy of the GNU General Public License along
717+ * with this program. If not, see <http://www.gnu.org/licenses/>.
718+ */
719+
720+#include <Accounts/Account>
721+#include <Accounts/Manager>
722+
723+#include <QDebug>
724+#include <QDir>
725+#include <QDomDocument>
726+#include <QDomElement>
727+#include <QFile>
728+#include <QSignalSpy>
729+#include <QTemporaryDir>
730+#include <QTest>
731+
732+#include <SystemSettings/ItemBase>
733+
734+#include "plugin.h"
735+
736+namespace QTest {
737+template<>
738+char *toString(const QSet<QString> &set)
739+{
740+ QByteArray ba = "QSet<QString>(";
741+ QStringList list = set.toList();
742+ ba += list.join(", ");
743+ ba += ")";
744+ return qstrdup(ba.data());
745+}
746+} // QTest namespace
747+
748+/* mocking libintl { */
749+static QHash<QString,QHash<QByteArray,QByteArray> > m_translations;
750+extern "C" {
751+char *dgettext(const char *domainname, const char *msgid)
752+{
753+ return (char *)m_translations[domainname].value(msgid).data();
754+}
755+char *dcgettext(const char *__domainname, const char *__msgid, int __category)
756+{
757+ Q_UNUSED(__category);
758+ return dgettext(__domainname, __msgid);
759+}
760+} // extern C
761+/* } mocking libintl */
762+
763+class PluginTest: public QObject
764+{
765+ Q_OBJECT
766+
767+ struct FileData {
768+ FileData() {}
769+ FileData(const QString &name, const QString &domain):
770+ name(name), domain(domain) {}
771+ QString name;
772+ QString domain;
773+ };
774+
775+public:
776+ PluginTest();
777+
778+private Q_SLOTS:
779+ void testKeywords_data();
780+ void testKeywords();
781+
782+private:
783+ void setDataDir(const QTemporaryDir &dir);
784+ void writeProvider(const QString &id, const QString &name,
785+ const QString &domain);
786+ void writeService(const QString &id, const QString &name,
787+ const QString &domain);
788+ void writeLibaccountsFile(const QString &type, const QString &id,
789+ const QString &name, const QString &domain);
790+ void createAccount(const QString &name);
791+
792+private:
793+ QHash<QString,FileData> m_providersData;
794+ QHash<QString,FileData> m_servicesData;
795+ QDir m_dataDir;
796+};
797+
798+PluginTest::PluginTest():
799+ QObject(0)
800+{
801+ m_providersData["provider_noname"] = FileData("", "");
802+ m_providersData["provider_nodomain"] = FileData("Happy", "");
803+ m_providersData["provider_translated"] = FileData("Joyful", "translations1");
804+
805+ m_servicesData["service_nodomain"] = FileData("Sad", "");
806+ m_servicesData["service_translated"] = FileData("Depressed", "translations1");
807+ m_servicesData["service_translated2"] = FileData("Depressed", "translations2");
808+
809+ m_translations["translations1"]["Happy"] = "Contento";
810+ m_translations["translations1"]["Joyful"] = "Gioioso";
811+ m_translations["translations1"]["Sad"] = "Triste";
812+ m_translations["translations1"]["Depressed"] = "Depresso1";
813+ m_translations["translations1"]["Black"] = "Nero";
814+ m_translations["translations1"]["White"] = "Bianco";
815+
816+ m_translations["translations2"]["Depressed"] = "Depresso2";
817+}
818+
819+void PluginTest::setDataDir(const QTemporaryDir &dir)
820+{
821+ QVERIFY(dir.isValid());
822+
823+ m_dataDir = QDir(dir.path());
824+
825+ QByteArray dataPath = dir.path().toUtf8();
826+ qputenv("ACCOUNTS", dataPath);
827+ qputenv("AG_PROVIDERS", dataPath);
828+ qputenv("AG_SERVICES", dataPath);
829+}
830+
831+void PluginTest::writeProvider(const QString &id, const QString &name,
832+ const QString &domain)
833+{
834+ writeLibaccountsFile("provider", id, name, domain);
835+}
836+
837+void PluginTest::writeService(const QString &id, const QString &name,
838+ const QString &domain)
839+{
840+ writeLibaccountsFile("service", id, name, domain);
841+}
842+
843+void PluginTest::writeLibaccountsFile(const QString &type, const QString &id,
844+ const QString &name, const QString &domain)
845+{
846+ QDomDocument doc;
847+ QDomElement root = doc.createElement(type);
848+ root.setAttribute("id", id);
849+ doc.appendChild(root);
850+
851+ QDomElement nameTag = doc.createElement("name");
852+ nameTag.appendChild(doc.createTextNode(name));
853+ root.appendChild(nameTag);
854+
855+ QDomElement domainTag = doc.createElement("translations");
856+ domainTag.appendChild(doc.createTextNode(domain));
857+ root.appendChild(domainTag);
858+
859+ if (type == "service") {
860+ QDomElement typeTag = doc.createElement("type");
861+ typeTag.appendChild(doc.createTextNode("something"));
862+ root.appendChild(typeTag);
863+ }
864+
865+ QFile file(m_dataDir.filePath(id + "." + type));
866+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
867+ qWarning() << "Could not write file" << file.fileName();
868+ return;
869+ }
870+
871+ file.write(doc.toString().toUtf8());
872+}
873+
874+void PluginTest::createAccount(const QString &name)
875+{
876+ Accounts::Manager *manager = new Accounts::Manager;
877+
878+ Accounts::Account *account = manager->createAccount("any");
879+ account->setDisplayName(name);
880+ account->syncAndBlock();
881+
882+ delete manager;
883+}
884+
885+void PluginTest::testKeywords_data()
886+{
887+ QTest::addColumn<QStringList>("providers");
888+ QTest::addColumn<QStringList>("services");
889+ QTest::addColumn<QStringList>("accountNames");
890+ QTest::addColumn<QStringList>("keywords");
891+
892+ QTest::newRow("provider, no name") <<
893+ (QStringList() << "provider_noname") <<
894+ QStringList() <<
895+ QStringList() <<
896+ (QStringList() << "provider_noname");
897+
898+ QTest::newRow("provider, untranslated") <<
899+ (QStringList() << "provider_nodomain") <<
900+ QStringList() <<
901+ QStringList() <<
902+ (QStringList() << "provider_nodomain" << "happy");
903+
904+ QTest::newRow("provider, translated") <<
905+ (QStringList() << "provider_translated") <<
906+ QStringList() <<
907+ QStringList() <<
908+ (QStringList() << "provider_translated" << "joyful" << "gioioso");
909+
910+ QTest::newRow("service, untranslated") <<
911+ QStringList() <<
912+ (QStringList() << "service_nodomain") <<
913+ QStringList() <<
914+ (QStringList() << "service_nodomain" << "sad");
915+
916+ QTest::newRow("service, translated 1") <<
917+ QStringList() <<
918+ (QStringList() << "service_translated") <<
919+ QStringList() <<
920+ (QStringList() << "service_translated" << "depressed" << "depresso1");
921+
922+ QTest::newRow("service, translated 2") <<
923+ QStringList() <<
924+ (QStringList() << "service_translated2") <<
925+ QStringList() <<
926+ (QStringList() << "service_translated2" << "depressed" << "depresso2");
927+
928+ QTest::newRow("one account, one word") <<
929+ QStringList() <<
930+ QStringList() <<
931+ (QStringList() << "tom@example.com") <<
932+ (QStringList() << "tom@example.com");
933+
934+ QTest::newRow("one account, many words") <<
935+ QStringList() <<
936+ QStringList() <<
937+ (QStringList() << "My little sweet account") <<
938+ (QStringList() << "my little sweet account");
939+
940+ QTest::newRow("combined") <<
941+ (QStringList() << "provider_translated" << "provider_nodomain") <<
942+ (QStringList() << "service_translated" << "service_translated2") <<
943+ (QStringList() << "john@invalid" << "harry@mysite.com") <<
944+ (QStringList() << "provider_translated" << "joyful" << "gioioso" <<
945+ "provider_nodomain" << "happy" <<
946+ "service_translated" << "depressed" << "depresso1" <<
947+ "service_translated2" << "depressed" << "depresso2" <<
948+ "john@invalid" << "harry@mysite.com");
949+}
950+
951+void PluginTest::testKeywords()
952+{
953+ QFETCH(QStringList, providers);
954+ QFETCH(QStringList, services);
955+ QFETCH(QStringList, accountNames);
956+ QFETCH(QStringList, keywords);
957+
958+ QTemporaryDir dataDir;
959+
960+ setDataDir(dataDir);
961+
962+ /* Create the needed files */
963+ Q_FOREACH(const QString &providerId, providers) {
964+ writeProvider(providerId,
965+ m_providersData[providerId].name,
966+ m_providersData[providerId].domain);
967+ }
968+
969+ Q_FOREACH(const QString &serviceId, services) {
970+ writeService(serviceId,
971+ m_servicesData[serviceId].name,
972+ m_servicesData[serviceId].domain);
973+ }
974+
975+ /* create the accounts */
976+ Q_FOREACH(const QString &displayName, accountNames) {
977+ createAccount(displayName);
978+ }
979+
980+ /* Now do the actual test */
981+ Plugin plugin;
982+
983+ SystemSettings::ItemBase *item = plugin.createItem(QVariantMap());
984+ QStringList pluginKeywords = item->keywords();
985+
986+ QCOMPARE(pluginKeywords.toSet(), keywords.toSet());
987+}
988+
989+QTEST_MAIN(PluginTest);
990+
991+#include "tst_plugin.moc"
992
993=== modified file 'tests/tests.pro'
994--- tests/tests.pro 2014-10-03 14:56:11 +0000
995+++ tests/tests.pro 2015-02-23 09:45:54 +0000
996@@ -5,4 +5,5 @@
997 client \
998 online-accounts-service \
999 online-accounts-ui \
1000- plugin
1001+ plugin \
1002+ system-settings-plugin

Subscribers

People subscribed via source and target branches

to all changes: