Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/jsxc.nextcloud.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLEDfan <LEDfan@users.noreply.github.com>2017-08-01 22:30:12 +0300
committerGitHub <noreply@github.com>2017-08-01 22:30:12 +0300
commite3793e3099c2d6e3b6750ab4b10aea89452e4054 (patch)
tree2d49d7743d281067e64a911318905cea80487c82
parent9d7e9d87cf5db20c727e7166db1ba9d0e1bfa951 (diff)
parentf32f47957ac98e8bfeab82c40657d1486804c831 (diff)
Merge pull request #52 from nextcloud/refresh_roster_delete_users
Include deleted users in refresh roster + run on installation + fix current user in roster
-rw-r--r--appinfo/application.php19
-rwxr-xr-xappinfo/info.xml7
-rw-r--r--lib/Migration/RefreshRoster.php75
-rw-r--r--lib/command/refreshroster.php10
-rw-r--r--lib/hooks.php4
-rw-r--r--lib/rosterpush.php69
-rw-r--r--lib/stanzahandlers/iq.php15
-rw-r--r--phpunit.xml4
-rw-r--r--tests/integration/db/IqRosterPushTest.php36
-rw-r--r--tests/integration/db/PresenceMapperTest.php63
-rw-r--r--tests/integration/db/StanzaMapperTest.php31
-rw-r--r--tests/unit/HooksTest.php160
-rw-r--r--tests/unit/RosterPushTest.php259
-rw-r--r--tests/unit/stanzahandlers/IQTest.php14
14 files changed, 743 insertions, 23 deletions
diff --git a/appinfo/application.php b/appinfo/application.php
index 55ffd3d..90cd530 100644
--- a/appinfo/application.php
+++ b/appinfo/application.php
@@ -13,6 +13,7 @@ use OCA\OJSXC\Db\MessageMapper;
use OCA\OJSXC\Db\PresenceMapper;
use OCA\OJSXC\Db\Stanza;
use OCA\OJSXC\Db\StanzaMapper;
+use OCA\OJSXC\Migration\RefreshRoster as RefreshRosterMigration;
use OCA\OJSXC\NewContentContainer;
use OCA\OJSXC\RosterPush;
use OCA\OJSXC\StanzaHandlers\IQ;
@@ -164,7 +165,8 @@ class Application extends App {
return new IQ(
$c->query('OJSXC_UserId'),
$c->query('Host'),
- $c->query('OCP\IUserManager')
+ $c->query('OCP\IUserManager'),
+ $c->query('OCP\IConfig')
);
});
@@ -211,7 +213,8 @@ class Application extends App {
$c->query('ServerContainer')->getUserManager(),
$c->query('ServerContainer')->getUserSession(),
$c->query('Host'),
- $c->query('IQRosterPushMapper')
+ $c->query('IQRosterPushMapper'),
+ $c->query('ServerContainer')->getDatabaseConnection()
);
});
@@ -243,17 +246,25 @@ class Application extends App {
/**
* Raw request body
*/
- $container->registerService('RawRequest', function($c) {
+ $container->registerService('RawRequest', function($c) {
return new RawRequest();
});
/**
* Data retriever
*/
- $container->registerService('DataRetriever', function($c) {
+ $container->registerService('DataRetriever', function($c) {
return new DataRetriever();
});
+ $container->registerService('OCA\OJSXC\Migration\RefreshRoster', function(IContainer $c) {
+ return new RefreshRosterMigration(
+ $c->query('RosterPush'),
+ $c->query('OCP\IConfig'),
+ $c->query('OCP\ILogger')
+ );
+ });
+
}
/**
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 4020ba7..9a94703 100755
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -53,4 +53,11 @@
<contactsmenu>
<provider>OCA\OJSXC\ContactsMenu\Providers\ChatProvider</provider>
</contactsmenu>
+
+ <repair-steps>
+ <install>
+ <step>OCA\OJSXC\Migration\RefreshRoster</step>
+ </install>
+ </repair-steps>
+
</info>
diff --git a/lib/Migration/RefreshRoster.php b/lib/Migration/RefreshRoster.php
new file mode 100644
index 0000000..d31b988
--- /dev/null
+++ b/lib/Migration/RefreshRoster.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace OCA\OJSXC\Migration;
+
+use OCA\OJSXC\RosterPush;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class RefreshRoster implements IRepairStep
+{
+
+ /**
+ * @var RosterPush
+ */
+ private $rosterPush;
+
+ /**
+ * @var IConfig
+ */
+ private $config;
+
+ /**
+ * @var ILogger
+ */
+ private $logger;
+
+ /**
+ * RefreshRoster constructor.
+ *
+ * @param RosterPush $rosterPush
+ * @param IConfig $config
+ * @param ILogger $logger
+ */
+ public function __construct(RosterPush $rosterPush, IConfig $config, ILogger $logger)
+ {
+ $this->rosterPush = $rosterPush;
+ $this->config = $config;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Returns the step's name
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return "Refresh the roster of all users when the app has been installed before.";
+ }
+
+ /**
+ * Run repair step.
+ * Must throw exception on error.
+ *
+ * @param IOutput $output
+ * @throws \Exception in case of failure
+ */
+ public function run(IOutput $output)
+ {
+ /**
+ * We want only to refresh the rosters if this app was installed before,
+ * since only then the rosters can be outdated.
+ */
+ if ($this->config->getAppValue('ojsxc', 'installed_version', null) !== null
+ && $this->config->getAppValue('ojsxc', 'serverType', 'internal') === 'internal') {
+ $stats = $this->rosterPush->refreshRoster();
+ $output->info("Updated " . $stats["updated"] . " roster items");
+ $this->logger->info("Updated " . $stats["updated"] . " roster items", ["app" => "OJSXC"]);
+ $output->info("Removed " . $stats["removed"] . " roster items");
+ $this->logger->info("Removed " . $stats["removed"] . " roster items", ["app" => "OJSXC"]);
+ }
+ }
+}
diff --git a/lib/command/refreshroster.php b/lib/command/refreshroster.php
index b3f9522..e11c783 100644
--- a/lib/command/refreshroster.php
+++ b/lib/command/refreshroster.php
@@ -39,12 +39,8 @@ class RefreshRoster extends Command
protected function execute(InputInterface $input, OutputInterface $output)
{
- $users = $this->userManager->search('');
-
- foreach ($users as $user) {
- $this->rosterPush->createOrUpdateRosterItem($user);
- }
-
- $output->writeln("<info>Refreshed " . count($users) . " rosters. </info>");
+ $stats = $this->rosterPush->refreshRoster();
+ $output->writeln("Updated " . $stats["updated"] . " roster items");
+ $output->writeln("Removed " . $stats["removed"] . " roster items");
}
}
diff --git a/lib/hooks.php b/lib/hooks.php
index 4e731c1..c9ecba5 100644
--- a/lib/hooks.php
+++ b/lib/hooks.php
@@ -2,8 +2,6 @@
namespace OCA\OJSXC;
-use OCA\OJSXC\Db\IQRosterPush;
-use OCA\OJSXC\Db\IQRosterPushMapper;
use OCA\OJSXC\Db\PresenceMapper;
use OCA\OJSXC\Db\StanzaMapper;
use OCP\IUserManager;
@@ -80,7 +78,7 @@ class Hooks
*/
public function onDeleteUser(IUser $user)
{
- $this->rosterPush->removeRosterItem($user);
+ $this->rosterPush->removeRosterItem($user->getUID());
// delete the presence record of this user
$this->presenceMapper->deletePresence($user->getUID());
diff --git a/lib/rosterpush.php b/lib/rosterpush.php
index f15bfdf..4771dea 100644
--- a/lib/rosterpush.php
+++ b/lib/rosterpush.php
@@ -4,6 +4,7 @@ namespace OCA\OJSXC;
use OCA\OJSXC\Db\IQRosterPush;
use OCA\OJSXC\Db\IQRosterPushMapper;
+use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\IUser;
@@ -29,16 +30,23 @@ class RosterPush
*/
private $userSession;
+ /**
+ * @var IDBConnection
+ */
+ private $db;
+
public function __construct(
IUserManager $userManager,
IUserSession $userSession,
$host,
- IQRosterPushMapper $iqRosterPushMapper
+ IQRosterPushMapper $iqRosterPushMapper,
+ IDbConnection $db
) {
$this->userManager = $userManager;
$this->userSession = $userSession;
$this->host = $host;
$this->iqRosterPushMapper = $iqRosterPushMapper;
+ $this->db = $db;
}
/**
@@ -64,22 +72,71 @@ class RosterPush
/**
* @see https://tools.ietf.org/html/rfc6121#section-2.1.6
- * @param IUser $user
+ * @param $userId
*/
- public function removeRosterItem(IUser $user)
+ public function removeRosterItem($userId)
{
$iq = new IQRosterPush();
- $iq->setJid($user->getUID());
- $iq->setName($user->getDisplayName());
+ $iq->setJid($userId);
$iq->setSubscription('remove');
$iq->setFrom('');
foreach ($this->userManager->search('') as $recipient) {
- if ($recipient->getUID() !== $user->getUID()) {
+ if ($recipient->getUID() !== $userId) {
$iq->setTo($recipient->getUID());
$this->iqRosterPushMapper->insert($iq);
}
}
}
+
+ /**
+ * @brief performs a completely roster fresh of all users. This will send
+ * a rosterPush for every existing user and a rosterPush for every
+ * user which was ever deleted. The deleted user is fetched from the
+ * `addressbookchanges` table.
+ */
+ public function refreshRoster()
+ {
+ $stats = [
+ "updated" => 0,
+ "removed" => 0
+ ];
+
+
+ foreach ($this->userManager->search('') as $user) {
+ $this->createOrUpdateRosterItem($user);
+ $stats["updated"]++;
+ }
+
+ /**
+ * Here we look into the addressbookchanges table for deletions
+ * of "contacts" in the system addressbook. This are actual users of the
+ * Nextcloud instance. Because this is a private API of Nextcloud it's
+ * encapsulated in a try/catch block.
+ */
+ try {
+ $query = "SELECT `id` FROM `*PREFIX*addressbooks` WHERE `principaluri`='principals/system/system' LIMIT 1";
+ $addressbooks = $this->db->executeQuery($query)->fetchAll();
+ $id = $addressbooks[0]['id'];
+
+ $query = "SELECT `uri` FROM `*PREFIX*addressbookchanges` AS ac1 WHERE `addressbookid` = ? AND `operation` = 3 AND `id`=(SELECT MAX(id) FROM `*PREFIX*addressbookchanges` AS ac2 WHERE `uri`=ac1.uri)"; // we use the subquery to always fetch the latest change
+
+ // Fetching all changes
+ $deletions = $this->db->executeQuery($query, [$id])->fetchAll();
+
+ foreach ($deletions as $deletion) {
+ $userid = $deletion['uri'];
+ $colonPlace = strpos($userid, ':');
+ $dotPlace = strrpos($userid, '.');
+ $userid = substr($userid, $colonPlace + 1, strlen($userid) - $dotPlace - $colonPlace);
+ $this->removeRosterItem($userid);
+ $stats["removed"]++;
+ }
+ } catch (\Exception $e) {
+ \OC::$server->getLogger()->logException($e);
+ }
+
+ return $stats;
+ }
}
diff --git a/lib/stanzahandlers/iq.php b/lib/stanzahandlers/iq.php
index 1d0aaba..9a7293c 100644
--- a/lib/stanzahandlers/iq.php
+++ b/lib/stanzahandlers/iq.php
@@ -3,6 +3,7 @@
namespace OCA\OJSXC\StanzaHandlers;
use OCA\OJSXC\Db\IQRoster;
+use OCP\IConfig;
use OCP\IUserManager;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
@@ -21,16 +22,23 @@ class IQ extends StanzaHandler
private $userManager;
/**
+ * @var IConfig
+ */
+ private $config;
+
+ /**
* IQ constructor.
*
* @param string $userId
* @param string $host
* @param IUserManager $userManager
+ * @param IConfig $config
*/
- public function __construct($userId, $host, IUserManager $userManager)
+ public function __construct($userId, $host, IUserManager $userManager, IConfig $config)
{
parent::__construct($userId, $host);
$this->userManager = $userManager;
+ $this->config = $config;
}
@@ -42,6 +50,9 @@ class IQ extends StanzaHandler
{
$this->to = $this->getAttribute($stanza, 'to');
+ // if in debug mode we show the own username in the roster for testing
+ $debugMode = $this->config->getSystemValue("debug");
+
if ($stanza['value'][0]['name'] === '{jabber:iq:roster}query') {
$id = $stanza['attributes']['id'];
$iqRoster = new IQRoster();
@@ -49,7 +60,7 @@ class IQ extends StanzaHandler
$iqRoster->setTo($this->from);
$iqRoster->setQid($id);
foreach ($this->userManager->search('') as $user) {
- if ($user->getUID() !== $this->userId) {
+ if ($debugMode || (strtolower($user->getUID()) !== $this->userId)) {
$iqRoster->addItem($user->getUID() . '@' . $this->host, $user->getDisplayName());
}
}
diff --git a/phpunit.xml b/phpunit.xml
index 7ae3f53..b6bced8 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -14,9 +14,13 @@
<exclude>
<directory suffix=".php">lib/ContactsMenu</directory>
<directory suffix=".php">lib/db</directory>
+ <!-- The following three files are tested in the integration test suite -->
<file>lib/ilock.php</file>
<file>lib/memlock.php</file>
<file>lib/dblock.php</file>
+ <!-- The following two files are simple wrappers around other code -->
+ <file>lib/command/refreshroster.php</file>
+ <file>lib/Migration/RefreshRoster.php</file>
</exclude>
</whitelist>
</filter>
diff --git a/tests/integration/db/IqRosterPushTest.php b/tests/integration/db/IqRosterPushTest.php
new file mode 100644
index 0000000..e6e8c0d
--- /dev/null
+++ b/tests/integration/db/IqRosterPushTest.php
@@ -0,0 +1,36 @@
+<?php
+namespace OCA\OJSXC\Db;
+
+use Sabre\Xml\Writer;
+use OCA\OJSXC\Utility\TestCase;
+
+class IqRosterPushTest extends TestCase
+{
+ public function testIqRoster()
+ {
+ $expected = '<body xmlns="http://jabber.org/protocol/httpbind"><iq to="jan@localhost" type="set" id="4"><query xmlns="jabber:iq:roster"><item jid="john@localhost" name="john" subscription="both"></item></query></iq></body>';
+
+ $writer = new Writer();
+ $writer->openMemory();
+ $writer->startElement('body');
+ $writer->writeAttribute('xmlns', 'http://jabber.org/protocol/httpbind');
+
+ $iqRosterPush = new IQRosterPush();
+ $iqRosterPush->setJid('john@localhost');
+ $iqRosterPush->setTo('jan@localhost');
+ $iqRosterPush->setName('john');
+ $iqRosterPush->setSubscription('both');
+
+ $this->assertEquals($iqRosterPush->getJid(), 'john@localhost');
+ $this->assertEquals($iqRosterPush->getTo(), 'jan@localhost');
+ $this->assertEquals($iqRosterPush->getName(), 'john');
+ $this->assertEquals($iqRosterPush->getSubscription(), 'both');
+
+ $writer->write($iqRosterPush); // needed to test the xmlSerialize function
+
+ $writer->endElement();
+ $result = $writer->outputMemory();
+
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/tests/integration/db/PresenceMapperTest.php b/tests/integration/db/PresenceMapperTest.php
index 11968c1..23b1624 100644
--- a/tests/integration/db/PresenceMapperTest.php
+++ b/tests/integration/db/PresenceMapperTest.php
@@ -480,4 +480,67 @@ class PresenceMapperTest extends MapperTestUtility
$this->assertArrayDbResultsEqual($expected, $result, ['userid', 'last_active', 'presence']);
}
+
+ public function deletePresenceProvider()
+ {
+ $input1 = new PresenceEntity();
+ $input1->setPresence('online');
+ $input1->setUserid('admin');
+ $input1->setLastActive(1000);
+
+ $input2 = new PresenceEntity();
+ $input2->setPresence('unavailable');
+ $input2->setUserid('foo');
+ $input2->setLastActive(1000);
+
+ $input3 = new PresenceEntity();
+ $input3->setPresence('xa');
+ $input3->setUserid('derp');
+ $input3->setLastActive(600);
+
+ $input4 = new PresenceEntity();
+ $input4->setPresence('chat');
+ $input4->setUserid('derpina');
+ $input4->setLastActive(400);
+
+ return [
+ [
+ [$input1, $input2, $input3, $input4],
+ [
+ [
+ 'userid' => 'foo',
+ 'presence' => 'unavailable',
+ 'last_active' => '1000',
+ ],
+ [
+ 'userid' => 'derp',
+ 'presence' => 'xa',
+ 'last_active' => '600',
+ ],
+ [
+ 'userid' => 'derpina',
+ 'presence' => 'chat',
+ 'last_active' => '400',
+ ],
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * @dataProvider deletePresenceProvider
+ */
+
+ public function testDeletePresence($inputs, $expected)
+ {
+ foreach ($inputs as $input) {
+ $this->mapper->setPresence($input);
+ }
+
+ $this->mapper->deletePresence('admin');
+
+ $result = $this->fetchAllAsArray();
+
+ $this->assertArrayDbResultsEqual($expected, $result, ['userid', 'last_active', 'presence']);
+ }
}
diff --git a/tests/integration/db/StanzaMapperTest.php b/tests/integration/db/StanzaMapperTest.php
index a2c09b0..279b2a1 100644
--- a/tests/integration/db/StanzaMapperTest.php
+++ b/tests/integration/db/StanzaMapperTest.php
@@ -111,4 +111,35 @@ class StanzaMapperTest extends MapperTestUtility
$this->assertEquals($stanza2->getTo(), $result[0]->getTo());
$this->assertEquals($stanza2->getStanza(), $result[0]->getStanza());
}
+
+
+ public function testDeleteByTo()
+ {
+ $stanza1 = new Stanza();
+ $stanza1->setFrom('jan@localhost');
+ $stanza1->setTo('john@localhost');
+ $stanza1->setStanza('abcd1');
+ $this->mapper->insert($stanza1);
+
+ $stanza2 = new Stanza();
+ $stanza2->setFrom('thomas@localhost');
+ $stanza2->setTo('jan@localhost');
+ $stanza2->setStanza('abcd2');
+ $this->mapper->insert($stanza2);
+
+ // check if two elements are inserted
+ $result = $this->fetchAllAsArray();
+ $this->assertArrayDbResultsEqual([
+ ['from' => 'jan@localhost', 'to' => 'john@localhost', 'stanza' => 'abcd1'],
+ ['from' => 'thomas@localhost', 'to' => 'jan@localhost', 'stanza' => 'abcd2']
+ ], $result, ['from', 'to', 'stanza']);
+
+
+ $this->mapper->deleteByTo('jan@localhost');
+
+ $result = $this->fetchAllAsArray();
+ $this->assertArrayDbResultsEqual([
+ ['from' => 'jan@localhost', 'to' => 'john@localhost', 'stanza' => 'abcd1']
+ ], $result, ['from', 'to', 'stanza']);
+ }
}
diff --git a/tests/unit/HooksTest.php b/tests/unit/HooksTest.php
new file mode 100644
index 0000000..f8a6f90
--- /dev/null
+++ b/tests/unit/HooksTest.php
@@ -0,0 +1,160 @@
+<?php
+
+
+namespace OCA\OJSXC;
+
+use OCA\OJSXC\Db\Presence;
+use OCA\OJSXC\Db\PresenceMapper;
+use OCA\OJSXC\Db\StanzaMapper;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use PHPUnit_Framework_MockObject_MockObject;
+use PHPUnit_Framework_TestCase;
+
+class HooksTest extends PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @var Hooks $hooks
+ */
+ private $hooks;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | IUserManager
+ */
+ private $userManager;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | IuserSession
+ */
+ private $userSession;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | RosterPush
+ */
+ private $rosterPush;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | PresenceMapper
+ */
+ private $presenceMapper;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | StanzaMapper
+ */
+ private $stanzaMapper;
+
+ public function setUp()
+ {
+ $this->userManager = $this->getMockBuilder('OCP\IUserManager')->setMethods(['listen', 'registerBackend', 'getBackends', 'removeBackend', 'clearBackends', 'get', 'userExists', 'checkPassword', 'search', 'searchDisplayName', 'createUser', 'createUserFromBackend', 'countUsers', 'callForAllUsers', 'countDisabledUsers', 'countSeenUsers', 'callForSeenUsers', 'getByEmail'])->getMock();
+
+ $this->userSession = $this->getMockBuilder('OCP\IUserSession')->setMethods(['listen', 'login', 'logout', 'setUser', 'getUser', 'isLoggedIn'])->getMock();
+
+
+ $this->rosterPush = $this->getMockBuilder('OCA\OJSXC\RosterPush')->disableOriginalConstructor()->getMock();
+
+ $this->presenceMapper = $this->getMockBuilder('OCA\OJSXC\Db\PresenceMapper')->disableOriginalConstructor()->getMock();
+
+ $this->stanzaMapper = $this->getMockBuilder('OCA\OJSXC\Db\StanzaMapper')->disableOriginalConstructor()->getMock();
+
+ $this->hooks = new Hooks(
+ $this->userManager,
+ $this->userSession,
+ $this->rosterPush,
+ $this->presenceMapper,
+ $this->stanzaMapper
+ );
+ }
+
+
+ public function testRegister()
+ {
+ $this->userManager->expects($this->at(0))
+ ->method('listen')
+ ->with('\OC\User', 'postCreateUser', [$this->hooks, 'onCreateUser']);
+
+ $this->userManager->expects($this->at(1))
+ ->method('listen')
+ ->with('\OC\User', 'postDelete', [$this->hooks, 'onDeleteUser']);
+
+ $this->userSession->expects($this->once())
+ ->method('listen')
+ ->with('\OC\User', 'changeUser', [$this->hooks, 'onChangeUser']);
+
+ $this->hooks->register();
+ }
+
+ public function testOnCreateUser()
+ {
+ $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
+
+ $this->rosterPush->expects($this->once())
+ ->method('createOrUpdateRosterItem')
+ ->with($user);
+
+ $this->hooks->onCreateUser($user, 'abc');
+ }
+
+ public function testOnDeleteUser()
+ {
+ $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
+
+ $user->expects($this->exactly(3))
+ ->method('getUID')
+ ->willReturn('test');
+
+ $this->rosterPush->expects($this->once())
+ ->method('removeRosterItem')
+ ->with('test');
+
+ $this->presenceMapper->expects($this->once())
+ ->method('deletePresence')
+ ->with('test');
+
+ $this->stanzaMapper->expects($this->once())
+ ->method('deleteByTo')
+ ->with('test');
+
+ $this->hooks->onDeleteUser($user);
+ }
+
+
+ public function testOnChangeUserEnabled()
+ {
+ $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
+
+ $hooks = $this->getMockBuilder('OCA\OJSXC\Hooks')->disableOriginalConstructor()->setMethods(['onCreateUser'])->getMock();
+
+ $hooks->expects($this->once())
+ ->method('onCreateUser')
+ ->with($user, '');
+
+ $hooks->onChangeUser($user, 'enabled', 'true');
+ }
+
+ public function testOnChangeUserDisabled()
+ {
+ $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
+
+ $hooks = $this->getMockBuilder('OCA\OJSXC\Hooks')->disableOriginalConstructor()->setMethods(['onDeleteUser'])->getMock();
+
+ $hooks->expects($this->once())
+ ->method('onDeleteUser')
+ ->with($user);
+
+ $hooks->onChangeUser($user, 'enabled', 'false');
+ }
+
+ public function testOnChangeUserDisplayName()
+ {
+ $user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
+
+ $hooks = $this->getMockBuilder('OCA\OJSXC\Hooks')->disableOriginalConstructor()->setMethods(['onCreateUser'])->getMock();
+
+ $hooks->expects($this->once())
+ ->method('onCreateUser')
+ ->with($user);
+
+ $hooks->onChangeUser($user, 'displayName', 'abc');
+ }
+}
diff --git a/tests/unit/RosterPushTest.php b/tests/unit/RosterPushTest.php
new file mode 100644
index 0000000..1021a9f
--- /dev/null
+++ b/tests/unit/RosterPushTest.php
@@ -0,0 +1,259 @@
+<?php
+
+namespace OCA\OJSXC;
+
+use OCA\OJSXC\Db\IQRosterPush;
+use OCA\OJSXC\Db\IQRosterPushMapper;
+use OCP\IDBConnection;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use PHPUnit_Framework_TestCase;
+
+class RosterPushTest extends PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @var RosterPush
+ */
+ private $rosterPush;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject | IUserManager
+ */
+ private $userManager;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject | IUserSession
+ */
+ private $userSession;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject | IQRosterPushMapper
+ */
+ private $iqRosterPushMapper;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject | IDBConnection
+ */
+ private $db;
+
+ public function setUp()
+ {
+ $this->userManager = $this->getMockBuilder('OCP\IUserManager')
+ ->disableOriginalConstructor()->getMock();
+
+ $this->userSession = $this->getMockBuilder('OCP\IUserSession')
+ ->disableOriginalConstructor()->getMock();
+
+ $this->iqRosterPushMapper = $this->getMockBuilder('OCA\OJSXC\Db\IQRosterPushMapper')
+ ->disableOriginalConstructor()->getMock();
+
+ $this->db = $this->getMockBuilder('OCP\IDbConnection')
+ ->disableOriginalConstructor()->getMock();
+
+ $this->rosterPush = new RosterPush(
+ $this->userManager,
+ $this->userSession,
+ 'localhost',
+ $this->iqRosterPushMapper,
+ $this->db
+ );
+ }
+
+ public function testRefreshRoster()
+ {
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject | RosterPush $rosterPush */
+ $rosterPush = $this->getMockBuilder('OCA\OJSXC\RosterPush')
+ ->setConstructorArgs([$this->userManager, $this->userSession, 'host', $this->iqRosterPushMapper, $this->db])
+ ->setMethods(['createOrUpdateRosterItem', 'removeRosterItem'])->getMock();
+
+ $user1 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user2 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user3 = $this->getMockBuilder('OCP\IUser')->getMock();
+
+ $this->userManager->expects($this->once())
+ ->method('search')
+ ->willReturn([$user1, $user2, $user3]);
+
+ $rosterPush->expects($this->at(0))
+ ->method('createOrUpdateRosterItem')
+ ->with($user1);
+
+ $rosterPush->expects($this->at(1))
+ ->method('createOrUpdateRosterItem')
+ ->with($user2);
+
+ $rosterPush->expects($this->at(2))
+ ->method('createOrUpdateRosterItem')
+ ->with($user3);
+
+ $resultStatement = $this->getMockBuilder('Doctrine\DBAL\Driver\ResultStatement')->getMock();
+
+ $resultStatement->expects($this->at(0))
+ ->method('fetchAll')
+ ->willReturn([["id" => 10]]);
+
+ $resultStatement->expects($this->at(1))
+ ->method('fetchAll')
+ ->willReturn([
+ ["uri" => 'Database:user1.vcf'],
+ ["uri" => 'Database:user2.vcf'],
+ ["uri" => 'Database:user3.vcf'],
+ ["uri" => 'Database:user4.vcf']
+ ]);
+
+ $this->db->expects($this->at(0))
+ ->method('executeQuery')
+ ->with('SELECT `id` FROM `*PREFIX*addressbooks` WHERE `principaluri`=\'principals/system/system\' LIMIT 1')
+ ->willReturn($resultStatement);
+
+ $this->db->expects($this->at(1))
+ ->method('executeQuery')
+ ->with('SELECT `uri` FROM `*PREFIX*addressbookchanges` AS ac1 WHERE `addressbookid` = ? AND `operation` = 3 AND `id`=(SELECT MAX(id) FROM `*PREFIX*addressbookchanges` AS ac2 WHERE `uri`=ac1.uri)', [10])
+ ->willReturn($resultStatement);
+
+
+ $rosterPush->expects($this->at(3))
+ ->method('removeRosterItem')
+ ->with('user1');
+
+ $rosterPush->expects($this->at(4))
+ ->method('removeRosterItem')
+ ->with('user2');
+
+ $rosterPush->expects($this->at(5))
+ ->method('removeRosterItem')
+ ->with('user3');
+
+ $rosterPush->expects($this->at(6))
+ ->method('removeRosterItem')
+ ->with('user4');
+
+ $stats = $rosterPush->refreshRoster();
+
+ $this->assertEquals($stats, ["removed" => 4, "updated" => 3]);
+ }
+
+ public function testRefreshRosterThrowsDuringRemove()
+ {
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject | RosterPush $rosterPush */
+ $rosterPush = $this->getMockBuilder('OCA\OJSXC\RosterPush')
+ ->setConstructorArgs([$this->userManager, $this->userSession, 'host', $this->iqRosterPushMapper, $this->db])
+ ->setMethods(['createOrUpdateRosterItem', 'removeRosterItem'])->getMock();
+
+ $user1 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user2 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user3 = $this->getMockBuilder('OCP\IUser')->getMock();
+
+ $this->userManager->expects($this->once())
+ ->method('search')
+ ->willReturn([$user1, $user2, $user3]);
+
+ $rosterPush->expects($this->at(0))
+ ->method('createOrUpdateRosterItem')
+ ->with($user1);
+
+ $rosterPush->expects($this->at(1))
+ ->method('createOrUpdateRosterItem')
+ ->with($user2);
+
+ $rosterPush->expects($this->at(2))
+ ->method('createOrUpdateRosterItem')
+ ->with($user3);
+
+ $this->db->expects($this->at(0))
+ ->method('executeQuery')
+ ->with('SELECT `id` FROM `*PREFIX*addressbooks` WHERE `principaluri`=\'principals/system/system\' LIMIT 1')
+ ->willThrowException(new \Exception("A random exception"));
+
+ $stats = $rosterPush->refreshRoster();
+
+ $this->assertEquals($stats, ["removed" => 0, "updated" => 3]);
+ }
+
+ public function testRemoveRosterItem()
+ {
+ $user1 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user1->expects($this->once())
+ ->method('getUID')
+ ->willReturn('user1');
+ $user2 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user2->expects($this->exactly(2))
+ ->method('getUID')
+ ->willReturn('user2');
+ $user3 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user3->expects($this->exactly(2))
+ ->method('getUID')
+ ->willReturn('user3');
+
+ $this->userManager->expects($this->once())
+ ->method('search')
+ ->willReturn([$user1, $user2, $user3]);
+
+ $stanza1 = new IQRosterPush();
+ $stanza1->setJid('user1');
+ $stanza1->setSubscription('remove');
+ $stanza1->setFrom('');
+ $stanza1->setTo('user2');
+
+ $stanza2 = new IQRosterPush();
+ $stanza2->setJid('user1');
+ $stanza2->setSubscription('remove');
+ $stanza2->setFrom('');
+ $stanza2->setTo('user3');
+
+ $this->iqRosterPushMapper->expects($this->at(0))
+ ->method('insert')
+ ->with($stanza1);
+
+ $this->iqRosterPushMapper->expects($this->at(1))
+ ->method('insert')
+ ->with($stanza2);
+
+ $this->rosterPush->removeRosterItem('user1');
+ }
+
+ public function testCreateOrUpdateRosterItem()
+ {
+ $user1 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user1->expects($this->exactly(5))
+ ->method('getUID')
+ ->willReturn('user1');
+ $user2 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user2->expects($this->exactly(2))
+ ->method('getUID')
+ ->willReturn('user2');
+ $user3 = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user3->expects($this->exactly(2))
+ ->method('getUID')
+ ->willReturn('user3');
+
+ $this->userManager->expects($this->once())
+ ->method('search')
+ ->willReturn([$user1, $user2, $user3]);
+
+ $stanza1 = new IQRosterPush();
+ $stanza1->setJid('user1');
+ $stanza1->setSubscription('both');
+ $stanza1->setFrom('');
+ $stanza1->setTo('user2');
+
+ $stanza2 = new IQRosterPush();
+ $stanza2->setJid('user1');
+ $stanza2->setSubscription('both');
+ $stanza2->setFrom('');
+ $stanza2->setTo('user3');
+
+ $this->iqRosterPushMapper->expects($this->at(0))
+ ->method('insert')
+ ->with($stanza1);
+
+ $this->iqRosterPushMapper->expects($this->at(1))
+ ->method('insert')
+ ->with($stanza2);
+
+ $this->rosterPush->createOrUpdateRosterItem($user1);
+ }
+}
diff --git a/tests/unit/stanzahandlers/IQTest.php b/tests/unit/stanzahandlers/IQTest.php
index 8ab22be..6c15c56 100644
--- a/tests/unit/stanzahandlers/IQTest.php
+++ b/tests/unit/stanzahandlers/IQTest.php
@@ -3,6 +3,7 @@
namespace OCA\OJSXC\StanzaHandlers;
use OCA\OJSXC\Db\IQRoster;
+use OCP\IConfig;
use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit_Framework_TestCase;
@@ -29,12 +30,18 @@ class IQTest extends PHPUnit_Framework_TestCase
*/
private $host;
+ /**
+ * @var PHPUnit_Framework_MockObject_MockObject | IConfig
+ */
+ private $config;
+
public function setUp()
{
$this->host = 'localhost';
$this->userId = 'john';
$this->userManager = $this->getMockBuilder('OCP\IUserManager')->disableOriginalConstructor()->getMock();
- $this->iq = new IQ($this->userId, $this->host, $this->userManager);
+ $this->config = $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock();
+ $this->iq = new IQ($this->userId, $this->host, $this->userManager, $this->config);
}
public function iqRosterProvider()
@@ -144,6 +151,11 @@ class IQTest extends PHPUnit_Framework_TestCase
*/
public function testIqRoster(array $stanza, array $users, $searchCount, $expected)
{
+ $this->config->expects($this->once())
+ ->method('getSystemValue')
+ ->with('debug')
+ ->will($this->returnValue(false));
+
$this->userManager->expects($searchCount)
->method('search')
->with('')