summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2016-02-01 16:17:45 +0100
committerThomas Müller <thomas.mueller@tmit.eu>2016-02-01 16:17:45 +0100
commitb4853f3fce696b8b89f0dd898b25d7fde93e1a92 (patch)
tree187da1e729be33aa2975f6f4462adea0e717111b
parenta2e13aea1513de2667a70d224396ed641a5dd179 (diff)
parent6dc793338acb3cd17716b5dc886885d0fb2d6181 (diff)
downloadnextcloud-server-b4853f3fce696b8b89f0dd898b25d7fde93e1a92.tar.gz
nextcloud-server-b4853f3fce696b8b89f0dd898b25d7fde93e1a92.zip
Merge pull request #21967 from owncloud/comments-webdav
Comments WebDAV adjustements
-rw-r--r--apps/dav/lib/comments/commentsplugin.php4
-rw-r--r--apps/dav/lib/connector/sabre/commentpropertiesplugin.php130
-rw-r--r--apps/dav/lib/connector/sabre/serverfactory.php1
-rw-r--r--apps/dav/tests/unit/connector/sabre/commentpropertiesplugin.php148
-rw-r--r--db_structure.xml43
-rw-r--r--lib/private/comments/manager.php139
-rw-r--r--lib/private/comments/managerfactory.php3
-rw-r--r--lib/private/user/user.php1
-rw-r--r--lib/public/comments/icommentsmanager.php48
-rw-r--r--tests/lib/comments/fakemanager.php10
-rw-r--r--tests/lib/comments/manager.php69
-rw-r--r--version.php2
12 files changed, 590 insertions, 8 deletions
diff --git a/apps/dav/lib/comments/commentsplugin.php b/apps/dav/lib/comments/commentsplugin.php
index 7e227fd2914..282c14df1e8 100644
--- a/apps/dav/lib/comments/commentsplugin.php
+++ b/apps/dav/lib/comments/commentsplugin.php
@@ -2,7 +2,7 @@
/**
* @author Arthur Schiwon <blizzz@owncloud.com>
*
- * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
@@ -88,7 +88,7 @@ class CommentsPlugin extends ServerPlugin {
$this->server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
$this->server->xml->classMap['DateTime'] = function(Writer $writer, \DateTime $value) {
- $writer->write($value->format('Y-m-d H:m:i'));
+ $writer->write(\Sabre\HTTP\toDate($value));
};
$this->server->on('report', [$this, 'onReport']);
diff --git a/apps/dav/lib/connector/sabre/commentpropertiesplugin.php b/apps/dav/lib/connector/sabre/commentpropertiesplugin.php
new file mode 100644
index 00000000000..a8d5f771122
--- /dev/null
+++ b/apps/dav/lib/connector/sabre/commentpropertiesplugin.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * @author Arthur Schiwon <blizzz@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Connector\Sabre;
+
+use OCP\Comments\ICommentsManager;
+use OCP\IUserSession;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\ServerPlugin;
+
+class CommentPropertiesPlugin extends ServerPlugin {
+
+ const PROPERTY_NAME_HREF = '{http://owncloud.org/ns}comments-href';
+ const PROPERTY_NAME_COUNT = '{http://owncloud.org/ns}comments-count';
+ const PROPERTY_NAME_UNREAD = '{http://owncloud.org/ns}comments-unread';
+
+ /** @var \Sabre\DAV\Server */
+ protected $server;
+
+ /** @var ICommentsManager */
+ private $commentsManager;
+
+ /** @var IUserSession */
+ private $userSession;
+
+ public function __construct(ICommentsManager $commentsManager, IUserSession $userSession) {
+ $this->commentsManager = $commentsManager;
+ $this->userSession = $userSession;
+ }
+
+ /**
+ * This initializes the plugin.
+ *
+ * This function is called by Sabre\DAV\Server, after
+ * addPlugin is called.
+ *
+ * This method should set up the required event subscriptions.
+ *
+ * @param \Sabre\DAV\Server $server
+ * @return void
+ */
+ function initialize(\Sabre\DAV\Server $server) {
+ $this->server = $server;
+ $this->server->on('propFind', array($this, 'handleGetProperties'));
+ }
+
+ /**
+ * Adds tags and favorites properties to the response,
+ * if requested.
+ *
+ * @param PropFind $propFind
+ * @param \Sabre\DAV\INode $node
+ * @return void
+ */
+ public function handleGetProperties(
+ PropFind $propFind,
+ \Sabre\DAV\INode $node
+ ) {
+ if (!($node instanceof File) && !($node instanceof Directory)) {
+ return;
+ }
+
+ $propFind->handle(self::PROPERTY_NAME_COUNT, function() use ($node) {
+ return $this->commentsManager->getNumberOfCommentsForObject('files', strval($node->getId()));
+ });
+
+ $propFind->handle(self::PROPERTY_NAME_HREF, function() use ($node) {
+ return $this->getCommentsLink($node);
+ });
+
+ $propFind->handle(self::PROPERTY_NAME_UNREAD, function() use ($node) {
+ return $this->getUnreadCount($node);
+ });
+ }
+
+ /**
+ * returns a reference to the comments node
+ *
+ * @param Node $node
+ * @return mixed|string
+ */
+ public function getCommentsLink(Node $node) {
+ $href = $this->server->getBaseUri();
+ $entryPoint = strrpos($href, '/webdav/');
+ if($entryPoint === false) {
+ // in case we end up somewhere else, unexpectedly.
+ return null;
+ }
+ $href = substr_replace($href, '/dav/', $entryPoint);
+ $href .= 'comments/files/' . rawurldecode($node->getId());
+ return $href;
+ }
+
+ /**
+ * returns the number of unread comments for the currently logged in user
+ * on the given file or directory node
+ *
+ * @param Node $node
+ * @return Int|null
+ */
+ public function getUnreadCount(Node $node) {
+ $user = $this->userSession->getUser();
+ if(is_null($user)) {
+ return null;
+ }
+
+ $lastRead = $this->commentsManager->getReadMark('files', strval($node->getId()), $user);
+
+ return $this->commentsManager->getNumberOfCommentsForObject('files', strval($node->getId()), $lastRead);
+ }
+
+}
diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php
index ee782f79a81..fa4fda46870 100644
--- a/apps/dav/lib/connector/sabre/serverfactory.php
+++ b/apps/dav/lib/connector/sabre/serverfactory.php
@@ -134,6 +134,7 @@ class ServerFactory {
if($this->userSession->isLoggedIn()) {
$server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
+ $server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
// custom properties plugin must be the last one
$server->addPlugin(
new \Sabre\DAV\PropertyStorage\Plugin(
diff --git a/apps/dav/tests/unit/connector/sabre/commentpropertiesplugin.php b/apps/dav/tests/unit/connector/sabre/commentpropertiesplugin.php
new file mode 100644
index 00000000000..f915c83c4a7
--- /dev/null
+++ b/apps/dav/tests/unit/connector/sabre/commentpropertiesplugin.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * @author Arthur Schiwon <blizzz@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Tests\Unit\Connector\Sabre;
+
+use \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin as CommentPropertiesPluginImplementation;
+
+class CommentsPropertiesPlugin extends \Test\TestCase {
+
+ /** @var CommentPropertiesPluginImplementation */
+ protected $plugin;
+ protected $commentsManager;
+ protected $userSession;
+ protected $server;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->commentsManager = $this->getMock('\OCP\Comments\ICommentsManager');
+ $this->userSession = $this->getMock('\OCP\IUserSession');
+
+ $this->server = $this->getMockBuilder('\Sabre\DAV\Server')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->plugin = new CommentPropertiesPluginImplementation($this->commentsManager, $this->userSession);
+ $this->plugin->initialize($this->server);
+ }
+
+ public function nodeProvider() {
+ $mocks = [];
+ foreach(['\OCA\DAV\Connector\Sabre\File', '\OCA\DAV\Connector\Sabre\Directory', '\Sabre\DAV\INode'] as $class) {
+ $mocks[] = $this->getMockBuilder($class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ return [
+ [$mocks[0], true],
+ [$mocks[1], true],
+ [$mocks[2], false]
+ ];
+ }
+
+ /**
+ * @dataProvider nodeProvider
+ * @param $node
+ * @param $expectedSuccessful
+ */
+ public function testHandleGetProperties($node, $expectedSuccessful) {
+ $propFind = $this->getMockBuilder('\Sabre\DAV\PropFind')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ if($expectedSuccessful) {
+ $propFind->expects($this->exactly(3))
+ ->method('handle');
+ } else {
+ $propFind->expects($this->never())
+ ->method('handle');
+ }
+
+ $this->plugin->handleGetProperties($propFind, $node);
+ }
+
+ public function baseUriProvider() {
+ return [
+ ['owncloud/remote.php/webdav/', '4567', 'owncloud/remote.php/dav/comments/files/4567'],
+ ['owncloud/remote.php/wicked/', '4567', null]
+ ];
+ }
+
+ /**
+ * @dataProvider baseUriProvider
+ * @param $baseUri
+ * @param $fid
+ * @param $expectedHref
+ */
+ public function testGetCommentsLink($baseUri, $fid, $expectedHref) {
+ $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $node->expects($this->any())
+ ->method('getId')
+ ->will($this->returnValue($fid));
+
+ $this->server->expects($this->once())
+ ->method('getBaseUri')
+ ->will($this->returnValue($baseUri));
+
+ $href = $this->plugin->getCommentsLink($node);
+ $this->assertSame($expectedHref, $href);
+ }
+
+ public function userProvider() {
+ return [
+ [$this->getMock('\OCP\IUser')],
+ [null]
+ ];
+ }
+
+ /**
+ * @dataProvider userProvider
+ * @param $user
+ */
+ public function testGetUnreadCount($user) {
+ $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $node->expects($this->any())
+ ->method('getId')
+ ->will($this->returnValue('4567'));
+
+ $this->userSession->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($user));
+
+ $this->commentsManager->expects($this->any())
+ ->method('getNumberOfCommentsForObject')
+ ->will($this->returnValue(42));
+
+ $unread = $this->plugin->getUnreadCount($node);
+ if(is_null($user)) {
+ $this->assertNull($unread);
+ } else {
+ $this->assertSame($unread, 42);
+ }
+ }
+
+}
diff --git a/db_structure.xml b/db_structure.xml
index 99bfa519b40..ea1b89e28da 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -1582,6 +1582,49 @@
<table>
<!--
+ default place to store per user and object read markers
+ -->
+ <name>*dbprefix*comments_read_markers</name>
+
+ <declaration>
+
+ <field>
+ <name>user_id</name>
+ <type>text</type>
+ <default></default>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+
+ <field>
+ <name>marker_datetime</name>
+ <type>timestamp</type>
+ <default></default>
+ <notnull>false</notnull>
+ </field>
+
+ <field>
+ <name>object_type</name>
+ <type>text</type>
+ <default></default>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+
+ <field>
+ <name>object_id</name>
+ <type>text</type>
+ <default></default>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+
+ </declaration>
+
+ </table>
+
+ <table>
+ <!--
Encrypted credentials storage
-->
<name>*dbprefix*credentials</name>
diff --git a/lib/private/comments/manager.php b/lib/private/comments/manager.php
index 64977c48895..23add3fd2c3 100644
--- a/lib/private/comments/manager.php
+++ b/lib/private/comments/manager.php
@@ -25,7 +25,9 @@ use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager;
use OCP\Comments\NotFoundException;
use OCP\IDBConnection;
+use OCP\IConfig;
use OCP\ILogger;
+use OCP\IUser;
class Manager implements ICommentsManager {
@@ -38,12 +40,17 @@ class Manager implements ICommentsManager {
/** @var IComment[] */
protected $commentsCache = [];
+ /** @var IConfig */
+ protected $config;
+
public function __construct(
IDBConnection $dbConn,
- ILogger $logger
+ ILogger $logger,
+ IConfig $config
) {
$this->dbConn = $dbConn;
$this->logger = $logger;
+ $this->config = $config;
}
/**
@@ -346,10 +353,12 @@ class Manager implements ICommentsManager {
/**
* @param $objectType string the object type, e.g. 'files'
* @param $objectId string the id of the object
+ * @param \DateTime $notOlderThan optional, timestamp of the oldest comments
+ * that may be returned
* @return Int
* @since 9.0.0
*/
- public function getNumberOfCommentsForObject($objectType, $objectId) {
+ public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null) {
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
->from('comments')
@@ -358,6 +367,12 @@ class Manager implements ICommentsManager {
->setParameter('type', $objectType)
->setParameter('id', $objectId);
+ if(!is_null($notOlderThan)) {
+ $query
+ ->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
+ ->setParameter('notOlderThan', $notOlderThan, 'datetime');
+ }
+
$resultStatement = $query->execute();
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
$resultStatement->closeCursor();
@@ -566,4 +581,124 @@ class Manager implements ICommentsManager {
return is_int($affectedRows);
}
+
+ /**
+ * deletes the read markers for the specified user
+ *
+ * @param \OCP\IUser $user
+ * @return bool
+ * @since 9.0.0
+ */
+ public function deleteReadMarksFromUser(IUser $user) {
+ $qb = $this->dbConn->getQueryBuilder();
+ $query = $qb->delete('comments_read_markers')
+ ->where($qb->expr()->eq('user_id', $qb->createParameter('user_id')))
+ ->setParameter('user_id', $user->getUID());
+
+ try {
+ $affectedRows = $query->execute();
+ } catch (DriverException $e) {
+ $this->logger->logException($e, ['app' => 'core_comments']);
+ return false;
+ }
+ return ($affectedRows > 0);
+ }
+
+ /**
+ * sets the read marker for a given file to the specified date for the
+ * provided user
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @param \DateTime $dateTime
+ * @param IUser $user
+ * @since 9.0.0
+ */
+ public function setReadMark($objectType, $objectId, \DateTime $dateTime, IUser $user) {
+ $this->checkRoleParameters('Object', $objectType, $objectId);
+
+ $qb = $this->dbConn->getQueryBuilder();
+ $values = [
+ 'user_id' => $qb->createNamedParameter($user->getUID()),
+ 'marker_datetime' => $qb->createNamedParameter($dateTime, 'datetime'),
+ 'object_type' => $qb->createNamedParameter($objectType),
+ 'object_id' => $qb->createNamedParameter($objectId),
+ ];
+
+ // Strategy: try to update, if this does not return affected rows, do an insert.
+ $affectedRows = $qb
+ ->update('comments_read_markers')
+ ->set('user_id', $values['user_id'])
+ ->set('marker_datetime', $values['marker_datetime'], 'datetime')
+ ->set('object_type', $values['object_type'])
+ ->set('object_id', $values['object_id'])
+ ->execute();
+
+ if ($affectedRows > 0) {
+ return;
+ }
+
+ $qb->insert('comments_read_markers')
+ ->values($values)
+ ->execute();
+ }
+
+ /**
+ * returns the read marker for a given file to the specified date for the
+ * provided user. It returns null, when the marker is not present, i.e.
+ * no comments were marked as read.
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @param IUser $user
+ * @return \DateTime|null
+ * @since 9.0.0
+ */
+ public function getReadMark($objectType, $objectId, IUser $user) {
+ $qb = $this->dbConn->getQueryBuilder();
+ $resultStatement = $qb->select('marker_datetime')
+ ->from('comments_read_markers')
+ ->where($qb->expr()->eq('user_id', $qb->createParameter('user_id')))
+ ->andWhere($qb->expr()->eq('object_type', $qb->createParameter('object_type')))
+ ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('object_id')))
+ ->setParameter('user_id', $user->getUID(), \PDO::PARAM_STR)
+ ->setParameter('object_type', $objectType, \PDO::PARAM_STR)
+ ->setParameter('object_id', $objectId, \PDO::PARAM_STR)
+ ->execute();
+
+ $data = $resultStatement->fetch();
+ $resultStatement->closeCursor();
+ if(!$data || is_null($data['marker_datetime'])) {
+ return null;
+ }
+
+ return new \DateTime($data['marker_datetime']);
+ }
+
+ /**
+ * deletes the read markers on the specified object
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @return bool
+ * @since 9.0.0
+ */
+ public function deleteReadMarksOnObject($objectType, $objectId) {
+ $this->checkRoleParameters('Object', $objectType, $objectId);
+
+ $qb = $this->dbConn->getQueryBuilder();
+ $query = $qb->delete('comments_read_markers')
+ ->where($qb->expr()->eq('object_type', $qb->createParameter('object_type')))
+ ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('object_id')))
+ ->setParameter('object_type', $objectType)
+ ->setParameter('object_id', $objectId);
+
+ try {
+ $affectedRows = $query->execute();
+ } catch (DriverException $e) {
+ $this->logger->logException($e, ['app' => 'core_comments']);
+ return false;
+ }
+ return ($affectedRows > 0);
+ }
}
diff --git a/lib/private/comments/managerfactory.php b/lib/private/comments/managerfactory.php
index 281e8ca7fef..d3f6c44e539 100644
--- a/lib/private/comments/managerfactory.php
+++ b/lib/private/comments/managerfactory.php
@@ -51,7 +51,8 @@ class ManagerFactory implements ICommentsManagerFactory {
public function getManager() {
return new Manager(
$this->serverContainer->getDatabaseConnection(),
- $this->serverContainer->getLogger()
+ $this->serverContainer->getLogger(),
+ $this->serverContainer->getConfig()
);
}
}
diff --git a/lib/private/user/user.php b/lib/private/user/user.php
index e8ce6b8cc87..5e556575118 100644
--- a/lib/private/user/user.php
+++ b/lib/private/user/user.php
@@ -211,6 +211,7 @@ class User implements IUser {
\OC\Files\Cache\Storage::remove('home::' . $this->uid);
\OC::$server->getCommentsManager()->deleteReferencesOfActor('user', $this->uid);
+ \OC::$server->getCommentsManager()->deleteReadMarksFromUser($this);
}
if ($this->emitter) {
diff --git a/lib/public/comments/icommentsmanager.php b/lib/public/comments/icommentsmanager.php
index b8fb3ca7f5d..f5b290bf8b2 100644
--- a/lib/public/comments/icommentsmanager.php
+++ b/lib/public/comments/icommentsmanager.php
@@ -115,10 +115,12 @@ interface ICommentsManager {
/**
* @param $objectType string the object type, e.g. 'files'
* @param $objectId string the id of the object
+ * @param \DateTime $notOlderThan optional, timestamp of the oldest comments
+ * that may be returned
* @return Int
* @since 9.0.0
*/
- public function getNumberOfCommentsForObject($objectType, $objectId);
+ public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null);
/**
* creates a new comment and returns it. At this point of time, it is not
@@ -188,4 +190,48 @@ interface ICommentsManager {
*/
public function deleteCommentsAtObject($objectType, $objectId);
+ /**
+ * sets the read marker for a given file to the specified date for the
+ * provided user
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @param \DateTime $dateTime
+ * @param \OCP\IUser $user
+ * @since 9.0.0
+ */
+ public function setReadMark($objectType, $objectId, \DateTime $dateTime, \OCP\IUser $user);
+
+ /**
+ * returns the read marker for a given file to the specified date for the
+ * provided user. It returns null, when the marker is not present, i.e.
+ * no comments were marked as read.
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @param \OCP\IUser $user
+ * @return \DateTime|null
+ * @since 9.0.0
+ */
+ public function getReadMark($objectType, $objectId, \OCP\IUser $user);
+
+ /**
+ * deletes the read markers for the specified user
+ *
+ * @param \OCP\IUser $user
+ * @return bool
+ * @since 9.0.0
+ */
+ public function deleteReadMarksFromUser(\OCP\IUser $user);
+
+ /**
+ * deletes the read markers on the specified object
+ *
+ * @param string $objectType
+ * @param string $objectId
+ * @return bool
+ * @since 9.0.0
+ */
+ public function deleteReadMarksOnObject($objectType, $objectId);
+
}
diff --git a/tests/lib/comments/fakemanager.php b/tests/lib/comments/fakemanager.php
index e5cf58dda4f..7186529e718 100644
--- a/tests/lib/comments/fakemanager.php
+++ b/tests/lib/comments/fakemanager.php
@@ -19,7 +19,7 @@ class FakeManager implements \OCP\Comments\ICommentsManager {
\DateTime $notOlderThan = null
) {}
- public function getNumberOfCommentsForObject($objectType, $objectId) {}
+ public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null) {}
public function create($actorType, $actorId, $objectType, $objectId) {}
@@ -30,4 +30,12 @@ class FakeManager implements \OCP\Comments\ICommentsManager {
public function deleteReferencesOfActor($actorType, $actorId) {}
public function deleteCommentsAtObject($objectType, $objectId) {}
+
+ public function setReadMark($objectType, $objectId, \DateTime $dateTime, \OCP\IUser $user) {}
+
+ public function getReadMark($objectType, $objectId, \OCP\IUser $user) {}
+
+ public function deleteReadMarksFromUser(\OCP\IUser $user) {}
+
+ public function deleteReadMarksOnObject($objectType, $objectId) {}
}
diff --git a/tests/lib/comments/manager.php b/tests/lib/comments/manager.php
index cc2eebb64d1..a71f78f2818 100644
--- a/tests/lib/comments/manager.php
+++ b/tests/lib/comments/manager.php
@@ -561,4 +561,73 @@ class Test_Comments_Manager extends TestCase
$this->assertTrue($wasSuccessful);
}
+ public function testSetMarkRead() {
+ $user = $this->getMock('\OCP\IUser');
+ $user->expects($this->any())
+ ->method('getUID')
+ ->will($this->returnValue('alice'));
+
+ $dateTimeSet = new \DateTime();
+
+ $manager = $this->getManager();
+ $manager->setReadMark('robot', '36', $dateTimeSet, $user);
+
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+
+ $this->assertEquals($dateTimeGet, $dateTimeSet);
+ }
+
+ public function testSetMarkReadUpdate() {
+ $user = $this->getMock('\OCP\IUser');
+ $user->expects($this->any())
+ ->method('getUID')
+ ->will($this->returnValue('alice'));
+
+ $dateTimeSet = new \DateTime('yesterday');
+
+ $manager = $this->getManager();
+ $manager->setReadMark('robot', '36', $dateTimeSet, $user);
+
+ $dateTimeSet = new \DateTime('today');
+ $manager->setReadMark('robot', '36', $dateTimeSet, $user);
+
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+
+ $this->assertEquals($dateTimeGet, $dateTimeSet);
+ }
+
+ public function testReadMarkDeleteUser() {
+ $user = $this->getMock('\OCP\IUser');
+ $user->expects($this->any())
+ ->method('getUID')
+ ->will($this->returnValue('alice'));
+
+ $dateTimeSet = new \DateTime();
+
+ $manager = $this->getManager();
+ $manager->setReadMark('robot', '36', $dateTimeSet, $user);
+
+ $manager->deleteReadMarksFromUser($user);
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+
+ $this->assertNull($dateTimeGet);
+ }
+
+ public function testReadMarkDeleteObject() {
+ $user = $this->getMock('\OCP\IUser');
+ $user->expects($this->any())
+ ->method('getUID')
+ ->will($this->returnValue('alice'));
+
+ $dateTimeSet = new \DateTime();
+
+ $manager = $this->getManager();
+ $manager->setReadMark('robot', '36', $dateTimeSet, $user);
+
+ $manager->deleteReadMarksOnObject('robot', '36');
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+
+ $this->assertNull($dateTimeGet);
+ }
+
}
diff --git a/version.php b/version.php
index a82e4ad1c0f..0b7eb6f79d2 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
-$OC_Version = array(9, 0, 0, 7);
+$OC_Version = array(9, 0, 0, 8);
// The human readable string
$OC_VersionString = '9.0 pre alpha';