aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php31
-rw-r--r--lib/private/Comments/Manager.php212
-rw-r--r--lib/private/DB/QueryBuilder/QuoteHelper.php2
-rw-r--r--lib/private/Repair/CleanTags.php2
-rw-r--r--lib/public/Comments/ICommentsManager.php12
-rw-r--r--tests/lib/Comments/FakeManager.php3
-rw-r--r--tests/lib/Comments/ManagerTest.php215
-rw-r--r--tests/lib/DB/QueryBuilder/QueryBuilderTest.php2
-rw-r--r--tests/lib/DB/QueryBuilder/QuoteHelperTest.php2
9 files changed, 312 insertions, 169 deletions
diff --git a/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php b/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php
index e48105f6d7a..66d6b335f40 100644
--- a/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/CommentPropertiesPlugin.php
@@ -42,6 +42,10 @@ class CommentPropertiesPlugin extends ServerPlugin {
/** @var IUserSession */
private $userSession;
+ private $cachedUnreadCount = [];
+
+ private $cachedFolders = [];
+
public function __construct(ICommentsManager $commentsManager, IUserSession $userSession) {
$this->commentsManager = $commentsManager;
$this->userSession = $userSession;
@@ -79,6 +83,18 @@ class CommentPropertiesPlugin extends ServerPlugin {
return;
}
+ // need prefetch ?
+ if ($node instanceof \OCA\DAV\Connector\Sabre\Directory
+ && $propFind->getDepth() !== 0
+ && !is_null($propFind->getStatus(self::PROPERTY_NAME_UNREAD))
+ ) {
+ $unreadCounts = $this->commentsManager->getNumberOfUnreadCommentsForFolder($node->getId(), $this->userSession->getUser());
+ $this->cachedFolders[] = $node->getPath();
+ foreach ($unreadCounts as $id => $count) {
+ $this->cachedUnreadCount[$id] = $count;
+ }
+ }
+
$propFind->handle(self::PROPERTY_NAME_COUNT, function() use ($node) {
return $this->commentsManager->getNumberOfCommentsForObject('files', strval($node->getId()));
});
@@ -88,7 +104,20 @@ class CommentPropertiesPlugin extends ServerPlugin {
});
$propFind->handle(self::PROPERTY_NAME_UNREAD, function() use ($node) {
- return $this->getUnreadCount($node);
+ if (isset($this->cachedUnreadCount[$node->getId()])) {
+ return $this->cachedUnreadCount[$node->getId()];
+ } else {
+ list($parentPath,) = \Sabre\Uri\split($node->getPath());
+ if ($parentPath === '') {
+ $parentPath = '/';
+ }
+ // if we already cached the folder this file is in we know there are no shares for this file
+ if (array_search($parentPath, $this->cachedFolders) === false) {
+ return $this->getUnreadCount($node);
+ } else {
+ return 0;
+ }
+ }
});
}
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index 1467fef727b..695d209b68f 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -21,9 +21,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Comments;
use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Platforms\MySqlPlatform;
use OCP\Comments\CommentsEvent;
use OCP\Comments\IComment;
use OCP\Comments\ICommentsEventHandler;
@@ -46,7 +48,7 @@ class Manager implements ICommentsManager {
/** @var IConfig */
protected $config;
- /** @var IComment[] */
+ /** @var IComment[] */
protected $commentsCache = [];
/** @var \Closure[] */
@@ -104,7 +106,7 @@ class Manager implements ICommentsManager {
* @throws \UnexpectedValueException
*/
protected function prepareCommentForDatabaseWrite(IComment $comment) {
- if( !$comment->getActorType()
+ if (!$comment->getActorType()
|| !$comment->getActorId()
|| !$comment->getObjectType()
|| !$comment->getObjectId()
@@ -113,17 +115,17 @@ class Manager implements ICommentsManager {
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
}
- if($comment->getId() === '') {
+ if ($comment->getId() === '') {
$comment->setChildrenCount(0);
$comment->setLatestChildDateTime(new \DateTime('0000-00-00 00:00:00', new \DateTimeZone('UTC')));
$comment->setLatestChildDateTime(null);
}
- if(is_null($comment->getCreationDateTime())) {
+ if (is_null($comment->getCreationDateTime())) {
$comment->setCreationDateTime(new \DateTime());
}
- if($comment->getParentId() !== '0') {
+ if ($comment->getParentId() !== '0') {
$comment->setTopmostParentId($this->determineTopmostParentId($comment->getParentId()));
} else {
$comment->setTopmostParentId('0');
@@ -143,7 +145,7 @@ class Manager implements ICommentsManager {
*/
protected function determineTopmostParentId($id) {
$comment = $this->get($id);
- if($comment->getParentId() === '0') {
+ if ($comment->getParentId() === '0') {
return $comment->getId();
} else {
return $this->determineTopmostParentId($comment->getId());
@@ -153,16 +155,16 @@ class Manager implements ICommentsManager {
/**
* updates child information of a comment
*
- * @param string $id
- * @param \DateTime $cDateTime the date time of the most recent child
+ * @param string $id
+ * @param \DateTime $cDateTime the date time of the most recent child
* @throws NotFoundException
*/
protected function updateChildrenInformation($id, \DateTime $cDateTime) {
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
- ->from('comments')
- ->where($qb->expr()->eq('parent_id', $qb->createParameter('id')))
- ->setParameter('id', $id);
+ ->from('comments')
+ ->where($qb->expr()->eq('parent_id', $qb->createParameter('id')))
+ ->setParameter('id', $id);
$resultStatement = $query->execute();
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
@@ -185,8 +187,8 @@ class Manager implements ICommentsManager {
* @throws \InvalidArgumentException
*/
protected function checkRoleParameters($role, $type, $id) {
- if(
- !is_string($type) || empty($type)
+ if (
+ !is_string($type) || empty($type)
|| !is_string($id) || empty($id)
) {
throw new \InvalidArgumentException($role . ' parameters must be string and not empty');
@@ -200,7 +202,7 @@ class Manager implements ICommentsManager {
*/
protected function cache(IComment $comment) {
$id = $comment->getId();
- if(empty($id)) {
+ if (empty($id)) {
return;
}
$this->commentsCache[strval($id)] = $comment;
@@ -228,11 +230,11 @@ class Manager implements ICommentsManager {
* @since 9.0.0
*/
public function get($id) {
- if(intval($id) === 0) {
+ if (intval($id) === 0) {
throw new \InvalidArgumentException('IDs must be translatable to a number in this implementation.');
}
- if(isset($this->commentsCache[$id])) {
+ if (isset($this->commentsCache[$id])) {
return $this->commentsCache[$id];
}
@@ -245,7 +247,7 @@ class Manager implements ICommentsManager {
$data = $resultStatement->fetch();
$resultStatement->closeCursor();
- if(!$data) {
+ if (!$data) {
throw new NotFoundException();
}
@@ -290,20 +292,20 @@ class Manager implements ICommentsManager {
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->select('*')
- ->from('comments')
- ->where($qb->expr()->eq('topmost_parent_id', $qb->createParameter('id')))
- ->orderBy('creation_timestamp', 'DESC')
- ->setParameter('id', $id);
+ ->from('comments')
+ ->where($qb->expr()->eq('topmost_parent_id', $qb->createParameter('id')))
+ ->orderBy('creation_timestamp', 'DESC')
+ ->setParameter('id', $id);
- if($limit > 0) {
+ if ($limit > 0) {
$query->setMaxResults($limit);
}
- if($offset > 0) {
+ if ($offset > 0) {
$query->setFirstResult($offset);
}
$resultStatement = $query->execute();
- while($data = $resultStatement->fetch()) {
+ while ($data = $resultStatement->fetch()) {
$comment = new Comment($this->normalizeDatabaseData($data));
$this->cache($comment);
$tree['replies'][] = [
@@ -332,37 +334,37 @@ class Manager implements ICommentsManager {
* @since 9.0.0
*/
public function getForObject(
- $objectType,
- $objectId,
- $limit = 0,
- $offset = 0,
- \DateTime $notOlderThan = null
+ $objectType,
+ $objectId,
+ $limit = 0,
+ $offset = 0,
+ \DateTime $notOlderThan = null
) {
$comments = [];
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->select('*')
- ->from('comments')
- ->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
- ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
- ->orderBy('creation_timestamp', 'DESC')
- ->setParameter('type', $objectType)
- ->setParameter('id', $objectId);
-
- if($limit > 0) {
+ ->from('comments')
+ ->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
+ ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
+ ->orderBy('creation_timestamp', 'DESC')
+ ->setParameter('type', $objectType)
+ ->setParameter('id', $objectId);
+
+ if ($limit > 0) {
$query->setMaxResults($limit);
}
- if($offset > 0) {
+ if ($offset > 0) {
$query->setFirstResult($offset);
}
- if(!is_null($notOlderThan)) {
+ if (!is_null($notOlderThan)) {
$query
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
->setParameter('notOlderThan', $notOlderThan, 'datetime');
}
$resultStatement = $query->execute();
- while($data = $resultStatement->fetch()) {
+ while ($data = $resultStatement->fetch()) {
$comment = new Comment($this->normalizeDatabaseData($data));
$this->cache($comment);
$comments[] = $comment;
@@ -383,13 +385,13 @@ class Manager implements ICommentsManager {
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null) {
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
- ->from('comments')
- ->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
- ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
- ->setParameter('type', $objectType)
- ->setParameter('id', $objectId);
+ ->from('comments')
+ ->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
+ ->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
+ ->setParameter('type', $objectType)
+ ->setParameter('id', $objectId);
- if(!is_null($notOlderThan)) {
+ if (!is_null($notOlderThan)) {
$query
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
->setParameter('notOlderThan', $notOlderThan, 'datetime');
@@ -402,6 +404,40 @@ class Manager implements ICommentsManager {
}
/**
+ * Get the number of unread comments for all files in a folder
+ *
+ * @param int $folderId
+ * @param IUser $user
+ * @return array [$fileId => $unreadCount]
+ */
+ public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user) {
+ $qb = $this->dbConn->getQueryBuilder();
+ $query = $qb->select('fileid', $qb->createFunction(
+ 'COUNT(' . $qb->getColumnName('c.id') . ')')
+ )->from('comments', 'c')
+ ->innerJoin('c', 'filecache', 'f', $qb->expr()->andX(
+ $qb->expr()->eq('c.object_type', $qb->createNamedParameter('files')),
+ $qb->expr()->eq('f.fileid', $qb->expr()->castColumn('c.object_id', IQueryBuilder::PARAM_INT))
+ ))
+ ->leftJoin('c', 'comments_read_markers', 'm', $qb->expr()->andX(
+ $qb->expr()->eq('m.object_type', $qb->createNamedParameter('files')),
+ $qb->expr()->eq('m.object_id', 'c.object_id'),
+ $qb->expr()->eq('m.user_id', $qb->createNamedParameter($user->getUID()))
+ ))
+ ->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($folderId)))
+ ->andWhere($qb->expr()->orX(
+ $qb->expr()->gt('c.creation_timestamp', 'marker_datetime'),
+ $qb->expr()->isNull('marker_datetime')
+ ))
+ ->groupBy('f.fileid');
+
+ $resultStatement = $query->execute();
+ return array_map(function ($count) {
+ return (int)$count;
+ }, $resultStatement->fetchAll(\PDO::FETCH_KEY_PAIR));
+ }
+
+ /**
* creates a new comment and returns it. At this point of time, it is not
* saved in the used data storage. Use save() after setting other fields
* of the comment (e.g. message or verb).
@@ -433,7 +469,7 @@ class Manager implements ICommentsManager {
* @since 9.0.0
*/
public function delete($id) {
- if(!is_string($id)) {
+ if (!is_string($id)) {
throw new \InvalidArgumentException('Parameter must be string');
}
@@ -481,16 +517,16 @@ class Manager implements ICommentsManager {
* @since 9.0.0
*/
public function save(IComment $comment) {
- if($this->prepareCommentForDatabaseWrite($comment)->getId() === '') {
+ if ($this->prepareCommentForDatabaseWrite($comment)->getId() === '') {
$result = $this->insert($comment);
} else {
$result = $this->update($comment);
}
- if($result && !!$comment->getParentId()) {
+ if ($result && !!$comment->getParentId()) {
$this->updateChildrenInformation(
- $comment->getParentId(),
- $comment->getCreationDateTime()
+ $comment->getParentId(),
+ $comment->getCreationDateTime()
);
$this->cache($comment);
}
@@ -509,17 +545,17 @@ class Manager implements ICommentsManager {
$affectedRows = $qb
->insert('comments')
->values([
- 'parent_id' => $qb->createNamedParameter($comment->getParentId()),
- 'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
- 'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
- 'actor_type' => $qb->createNamedParameter($comment->getActorType()),
- 'actor_id' => $qb->createNamedParameter($comment->getActorId()),
- 'message' => $qb->createNamedParameter($comment->getMessage()),
- 'verb' => $qb->createNamedParameter($comment->getVerb()),
- 'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
- 'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
- 'object_type' => $qb->createNamedParameter($comment->getObjectType()),
- 'object_id' => $qb->createNamedParameter($comment->getObjectId()),
+ 'parent_id' => $qb->createNamedParameter($comment->getParentId()),
+ 'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
+ 'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
+ 'actor_type' => $qb->createNamedParameter($comment->getActorType()),
+ 'actor_id' => $qb->createNamedParameter($comment->getActorId()),
+ 'message' => $qb->createNamedParameter($comment->getMessage()),
+ 'verb' => $qb->createNamedParameter($comment->getVerb()),
+ 'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
+ 'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
+ 'object_type' => $qb->createNamedParameter($comment->getObjectType()),
+ 'object_id' => $qb->createNamedParameter($comment->getObjectId()),
])
->execute();
@@ -548,22 +584,22 @@ class Manager implements ICommentsManager {
$qb = $this->dbConn->getQueryBuilder();
$affectedRows = $qb
->update('comments')
- ->set('parent_id', $qb->createNamedParameter($comment->getParentId()))
- ->set('topmost_parent_id', $qb->createNamedParameter($comment->getTopmostParentId()))
- ->set('children_count', $qb->createNamedParameter($comment->getChildrenCount()))
- ->set('actor_type', $qb->createNamedParameter($comment->getActorType()))
- ->set('actor_id', $qb->createNamedParameter($comment->getActorId()))
- ->set('message', $qb->createNamedParameter($comment->getMessage()))
- ->set('verb', $qb->createNamedParameter($comment->getVerb()))
- ->set('creation_timestamp', $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'))
- ->set('latest_child_timestamp', $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'))
- ->set('object_type', $qb->createNamedParameter($comment->getObjectType()))
- ->set('object_id', $qb->createNamedParameter($comment->getObjectId()))
+ ->set('parent_id', $qb->createNamedParameter($comment->getParentId()))
+ ->set('topmost_parent_id', $qb->createNamedParameter($comment->getTopmostParentId()))
+ ->set('children_count', $qb->createNamedParameter($comment->getChildrenCount()))
+ ->set('actor_type', $qb->createNamedParameter($comment->getActorType()))
+ ->set('actor_id', $qb->createNamedParameter($comment->getActorId()))
+ ->set('message', $qb->createNamedParameter($comment->getMessage()))
+ ->set('verb', $qb->createNamedParameter($comment->getVerb()))
+ ->set('creation_timestamp', $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'))
+ ->set('latest_child_timestamp', $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'))
+ ->set('object_type', $qb->createNamedParameter($comment->getObjectType()))
+ ->set('object_id', $qb->createNamedParameter($comment->getObjectId()))
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter('id', $comment->getId())
->execute();
- if($affectedRows === 0) {
+ if ($affectedRows === 0) {
throw new NotFoundException('Comment to update does ceased to exist');
}
@@ -587,8 +623,8 @@ class Manager implements ICommentsManager {
$qb = $this->dbConn->getQueryBuilder();
$affectedRows = $qb
->update('comments')
- ->set('actor_type', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
- ->set('actor_id', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
+ ->set('actor_type', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
+ ->set('actor_id', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
->where($qb->expr()->eq('actor_type', $qb->createParameter('type')))
->andWhere($qb->expr()->eq('actor_id', $qb->createParameter('id')))
->setParameter('type', $actorType)
@@ -662,19 +698,19 @@ class Manager implements ICommentsManager {
$qb = $this->dbConn->getQueryBuilder();
$values = [
- 'user_id' => $qb->createNamedParameter($user->getUID()),
+ 'user_id' => $qb->createNamedParameter($user->getUID()),
'marker_datetime' => $qb->createNamedParameter($dateTime, 'datetime'),
- 'object_type' => $qb->createNamedParameter($objectType),
- 'object_id' => $qb->createNamedParameter($objectId),
+ '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('user_id', $values['user_id'])
->set('marker_datetime', $values['marker_datetime'])
- ->set('object_type', $values['object_type'])
- ->set('object_id', $values['object_id'])
+ ->set('object_type', $values['object_type'])
+ ->set('object_id', $values['object_id'])
->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')))
@@ -717,7 +753,7 @@ class Manager implements ICommentsManager {
$data = $resultStatement->fetch();
$resultStatement->closeCursor();
- if(!$data || is_null($data['marker_datetime'])) {
+ if (!$data || is_null($data['marker_datetime'])) {
return null;
}
@@ -774,10 +810,10 @@ class Manager implements ICommentsManager {
* \OutOfBoundsException has to thrown.
*/
public function registerDisplayNameResolver($type, \Closure $closure) {
- if(!is_string($type)) {
+ if (!is_string($type)) {
throw new \InvalidArgumentException('String expected.');
}
- if(isset($this->displayNameResolvers[$type])) {
+ if (isset($this->displayNameResolvers[$type])) {
throw new \OutOfBoundsException('Displayname resolver for this type already registered');
}
$this->displayNameResolvers[$type] = $closure;
@@ -797,10 +833,10 @@ class Manager implements ICommentsManager {
* provided ID is unknown. It must be ensured that a string is returned.
*/
public function resolveDisplayName($type, $id) {
- if(!is_string($type)) {
+ if (!is_string($type)) {
throw new \InvalidArgumentException('String expected.');
}
- if(!isset($this->displayNameResolvers[$type])) {
+ if (!isset($this->displayNameResolvers[$type])) {
throw new \OutOfBoundsException('No Displayname resolver for this type registered');
}
return (string)$this->displayNameResolvers[$type]($id);
@@ -812,7 +848,7 @@ class Manager implements ICommentsManager {
* @return \OCP\Comments\ICommentsEventHandler[]
*/
private function getEventHandlers() {
- if(!empty($this->eventHandlers)) {
+ if (!empty($this->eventHandlers)) {
return $this->eventHandlers;
}
diff --git a/lib/private/DB/QueryBuilder/QuoteHelper.php b/lib/private/DB/QueryBuilder/QuoteHelper.php
index 041718bce5a..705c3a89712 100644
--- a/lib/private/DB/QueryBuilder/QuoteHelper.php
+++ b/lib/private/DB/QueryBuilder/QuoteHelper.php
@@ -73,7 +73,7 @@ class QuoteHelper {
return $string;
}
- return $alias . '.`' . $columnName . '`';
+ return '`' . $alias . '`.`' . $columnName . '`';
}
return '`' . $string . '`';
diff --git a/lib/private/Repair/CleanTags.php b/lib/private/Repair/CleanTags.php
index 8b62395a501..9b44fb1e671 100644
--- a/lib/private/Repair/CleanTags.php
+++ b/lib/private/Repair/CleanTags.php
@@ -173,7 +173,7 @@ class CleanTags implements IRepairStep {
$qb->select('d.' . $deleteId)
->from($deleteTable, 'd')
- ->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, ' s.' . $sourceId))
+ ->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, 's.' . $sourceId))
->where(
$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
)
diff --git a/lib/public/Comments/ICommentsManager.php b/lib/public/Comments/ICommentsManager.php
index b43d5e8800b..f088ad9f70d 100644
--- a/lib/public/Comments/ICommentsManager.php
+++ b/lib/public/Comments/ICommentsManager.php
@@ -23,6 +23,8 @@
*/
namespace OCP\Comments;
+use OCP\IUser;
+
/**
* Interface ICommentsManager
*
@@ -126,6 +128,16 @@ interface ICommentsManager {
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null);
/**
+ * Get the number of unread comments for all files in a folder
+ *
+ * @param int $folderId
+ * @param IUser $user
+ * @return array [$fileId => $unreadCount]
+ * @since 12.0.0
+ */
+ public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user);
+
+ /**
* creates a new comment and returns it. At this point of time, it is not
* saved in the used data storage. Use save() after setting other fields
* of the comment (e.g. message or verb).
diff --git a/tests/lib/Comments/FakeManager.php b/tests/lib/Comments/FakeManager.php
index dfb8f21b64b..840961fb901 100644
--- a/tests/lib/Comments/FakeManager.php
+++ b/tests/lib/Comments/FakeManager.php
@@ -1,6 +1,7 @@
<?php
namespace Test\Comments;
+use OCP\IUser;
/**
* Class FakeManager
@@ -44,4 +45,6 @@ class FakeManager implements \OCP\Comments\ICommentsManager {
public function registerDisplayNameResolver($type, \Closure $closure) {}
public function resolveDisplayName($type, $id) {}
+
+ public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user) {}
}
diff --git a/tests/lib/Comments/ManagerTest.php b/tests/lib/Comments/ManagerTest.php
index a320366f29e..24c634be137 100644
--- a/tests/lib/Comments/ManagerTest.php
+++ b/tests/lib/Comments/ManagerTest.php
@@ -6,7 +6,9 @@ use OC\Comments\Comment;
use OCP\Comments\CommentsEvent;
use OCP\Comments\ICommentsEventHandler;
use OCP\Comments\ICommentsManager;
+use OCP\IDBConnection;
use OCP\IUser;
+use Test\Files\Storage\DummyUser;
use Test\TestCase;
/**
@@ -15,37 +17,44 @@ use Test\TestCase;
* @group DB
*/
class ManagerTest extends TestCase {
+ /** @var IDBConnection */
+ private $connection;
public function setUp() {
parent::setUp();
- $sql = \OC::$server->getDatabaseConnection()->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
- \OC::$server->getDatabaseConnection()->prepare($sql)->execute();
+ $this->connection = \OC::$server->getDatabaseConnection();
+
+ $sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
+ $this->connection->prepare($sql)->execute();
}
- protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null) {
- if(is_null($creationDT)) {
+ protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null) {
+ if (is_null($creationDT)) {
$creationDT = new \DateTime();
}
- if(is_null($latestChildDT)) {
+ if (is_null($latestChildDT)) {
$latestChildDT = new \DateTime('yesterday');
}
+ if (is_null($objectId)) {
+ $objectId = 'file64';
+ }
- $qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $qb = $this->connection->getQueryBuilder();
$qb
->insert('comments')
->values([
- 'parent_id' => $qb->createNamedParameter($parentId),
- 'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
- 'children_count' => $qb->createNamedParameter(2),
- 'actor_type' => $qb->createNamedParameter('users'),
- 'actor_id' => $qb->createNamedParameter('alice'),
- 'message' => $qb->createNamedParameter('nice one'),
- 'verb' => $qb->createNamedParameter('comment'),
- 'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
- 'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
- 'object_type' => $qb->createNamedParameter('files'),
- 'object_id' => $qb->createNamedParameter('file64'),
+ 'parent_id' => $qb->createNamedParameter($parentId),
+ 'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
+ 'children_count' => $qb->createNamedParameter(2),
+ 'actor_type' => $qb->createNamedParameter('users'),
+ 'actor_id' => $qb->createNamedParameter('alice'),
+ 'message' => $qb->createNamedParameter('nice one'),
+ 'verb' => $qb->createNamedParameter('comment'),
+ 'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
+ 'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
+ 'object_type' => $qb->createNamedParameter('files'),
+ 'object_id' => $qb->createNamedParameter($objectId),
])
->execute();
@@ -83,17 +92,17 @@ class ManagerTest extends TestCase {
$qb
->insert('comments')
->values([
- 'parent_id' => $qb->createNamedParameter('2'),
- 'topmost_parent_id' => $qb->createNamedParameter('1'),
- 'children_count' => $qb->createNamedParameter(2),
- 'actor_type' => $qb->createNamedParameter('users'),
- 'actor_id' => $qb->createNamedParameter('alice'),
- 'message' => $qb->createNamedParameter('nice one'),
- 'verb' => $qb->createNamedParameter('comment'),
- 'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
- 'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
- 'object_type' => $qb->createNamedParameter('files'),
- 'object_id' => $qb->createNamedParameter('file64'),
+ 'parent_id' => $qb->createNamedParameter('2'),
+ 'topmost_parent_id' => $qb->createNamedParameter('1'),
+ 'children_count' => $qb->createNamedParameter(2),
+ 'actor_type' => $qb->createNamedParameter('users'),
+ 'actor_id' => $qb->createNamedParameter('alice'),
+ 'message' => $qb->createNamedParameter('nice one'),
+ 'verb' => $qb->createNamedParameter('comment'),
+ 'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
+ 'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
+ 'object_type' => $qb->createNamedParameter('files'),
+ 'object_id' => $qb->createNamedParameter('file64'),
])
->execute();
@@ -149,7 +158,7 @@ class ManagerTest extends TestCase {
$this->assertSame(count($tree['replies']), 3);
// one level deep
- foreach($tree['replies'] as $reply) {
+ foreach ($tree['replies'] as $reply) {
$this->assertTrue($reply['comment'] instanceof \OCP\Comments\IComment);
$this->assertSame($reply['comment']->getId(), strval($id));
$this->assertSame(count($reply['replies']), 0);
@@ -171,7 +180,7 @@ class ManagerTest extends TestCase {
$this->assertSame(count($tree['replies']), 0);
// one level deep
- foreach($tree['replies'] as $reply) {
+ foreach ($tree['replies'] as $reply) {
throw new \Exception('This ain`t happen');
}
}
@@ -233,14 +242,14 @@ class ManagerTest extends TestCase {
$comments = $manager->getForObject('files', 'file64', 3, $offset);
$this->assertTrue(is_array($comments));
- foreach($comments as $comment) {
+ foreach ($comments as $comment) {
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$this->assertSame($comment->getMessage(), 'nice one');
$this->assertSame($comment->getId(), strval($idToVerify));
$idToVerify--;
}
$offset += 3;
- } while(count($comments) > 0);
+ } while (count($comments) > 0);
}
public function testGetForObjectWithDateTimeConstraint() {
@@ -272,7 +281,7 @@ class ManagerTest extends TestCase {
$comments = $manager->getForObject('files', 'file64', 3, $offset, new \DateTime('-4 hours'));
$this->assertTrue(is_array($comments));
- foreach($comments as $comment) {
+ foreach ($comments as $comment) {
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$this->assertSame($comment->getMessage(), 'nice one');
$this->assertSame($comment->getId(), strval($idToVerify));
@@ -280,11 +289,11 @@ class ManagerTest extends TestCase {
$idToVerify--;
}
$offset += 3;
- } while(count($comments) > 0);
+ } while (count($comments) > 0);
}
public function testGetNumberOfCommentsForObject() {
- for($i = 1; $i < 5; $i++) {
+ for ($i = 1; $i < 5; $i++) {
$this->addDatabaseEntry(0, 0);
}
@@ -297,6 +306,52 @@ class ManagerTest extends TestCase {
$this->assertSame($amount, 4);
}
+ public function testGetNumberOfUnreadCommentsForFolder() {
+ // 2 comment for 1111 with 1 before read marker
+ // 2 comments for 1112 with no read marker
+ // 1 comment for 1113 before read marker
+ // 1 comment for 1114 with no read marker
+ $this->addDatabaseEntry(0, 0, null, null, '1112');
+ for ($i = 1; $i < 5; $i++) {
+ $this->addDatabaseEntry(0, 0, null, null, '111' . $i);
+ }
+ $this->addDatabaseEntry(0, 0, (new \DateTime())->modify('-2 days'), null, '1111');
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->any())
+ ->method('getUID')
+ ->will($this->returnValue('comment_test'));
+
+ $manager = $this->getManager();
+
+ $manager->setReadMark('files', '1111', (new \DateTime())->modify('-1 days'), $user);
+ $manager->setReadMark('files', '1113', (new \DateTime()), $user);
+
+ $query = $this->connection->getQueryBuilder();
+ $query->insert('filecache')
+ ->values([
+ 'fileid' => $query->createParameter('fileid'),
+ 'parent' => $query->createNamedParameter(1000),
+ 'size' => $query->createNamedParameter(10),
+ 'mtime' => $query->createNamedParameter(10),
+ 'storage_mtime' => $query->createNamedParameter(10),
+ 'path' => $query->createParameter('path'),
+ 'path_hash' => $query->createParameter('path'),
+ ]);
+
+ for ($i = 1111; $i < 1115; $i++) {
+ $query->setParameter('path', 'path_' . $i);
+ $query->setParameter('fileid', $i);
+ $query->execute();
+ }
+
+ $amount = $manager->getNumberOfUnreadCommentsForFolder(1000, $user);
+ $this->assertEquals([
+ '1111' => 1,
+ '1112' => 2,
+ '1114' => 1,
+ ], $amount);
+ }
+
public function invalidCreateArgsProvider() {
return [
['', 'aId-1', 'oType-1', 'oId-1'],
@@ -380,10 +435,10 @@ class ManagerTest extends TestCase {
$manager = $this->getManager();
$comment = new Comment();
$comment
- ->setActor('users', 'alice')
- ->setObject('files', 'file64')
- ->setMessage('very beautiful, I am impressed!')
- ->setVerb('comment');
+ ->setActor('users', 'alice')
+ ->setObject('files', 'file64')
+ ->setMessage('very beautiful, I am impressed!')
+ ->setVerb('comment');
$manager->save($comment);
@@ -401,10 +456,10 @@ class ManagerTest extends TestCase {
$manager = $this->getManager();
$comment = new Comment();
$comment
- ->setActor('users', 'alice')
- ->setObject('files', 'file64')
- ->setMessage('very beautiful, I am impressed!')
- ->setVerb('comment');
+ ->setActor('users', 'alice')
+ ->setObject('files', 'file64')
+ ->setMessage('very beautiful, I am impressed!')
+ ->setVerb('comment');
$manager->save($comment);
@@ -428,16 +483,16 @@ class ManagerTest extends TestCase {
$manager = $this->getManager();
- for($i = 0; $i < 3; $i++) {
+ for ($i = 0; $i < 3; $i++) {
$comment = new Comment();
$comment
- ->setActor('users', 'alice')
- ->setObject('files', 'file64')
- ->setParentId(strval($id))
- ->setMessage('full ack')
- ->setVerb('comment')
- // setting the creation time avoids using sleep() while making sure to test with different timestamps
- ->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
+ ->setActor('users', 'alice')
+ ->setObject('files', 'file64')
+ ->setParentId(strval($id))
+ ->setMessage('full ack')
+ ->setVerb('comment')
+ // setting the creation time avoids using sleep() while making sure to test with different timestamps
+ ->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
$manager->save($comment);
@@ -450,11 +505,11 @@ class ManagerTest extends TestCase {
public function invalidActorArgsProvider() {
return
- [
- ['', ''],
- [1, 'alice'],
- ['users', 1],
- ];
+ [
+ ['', ''],
+ [1, 'alice'],
+ ['users', 1],
+ ];
}
/**
@@ -482,7 +537,7 @@ class ManagerTest extends TestCase {
$wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
$this->assertTrue($wasSuccessful);
- foreach($ids as $id) {
+ foreach ($ids as $id) {
$comment = $manager->get(strval($id));
$this->assertSame($comment->getActorType(), ICommentsManager::DELETED_USER);
$this->assertSame($comment->getActorId(), ICommentsManager::DELETED_USER);
@@ -516,11 +571,11 @@ class ManagerTest extends TestCase {
public function invalidObjectArgsProvider() {
return
- [
- ['', ''],
- [1, 'file64'],
- ['files', 1],
- ];
+ [
+ ['', ''],
+ [1, 'file64'],
+ ['files', 1],
+ ];
}
/**
@@ -549,7 +604,7 @@ class ManagerTest extends TestCase {
$this->assertTrue($wasSuccessful);
$verified = 0;
- foreach($ids as $id) {
+ foreach ($ids as $id) {
try {
$manager->get(strval($id));
} catch (\OCP\Comments\NotFoundException $e) {
@@ -575,7 +630,7 @@ class ManagerTest extends TestCase {
$manager = $this->getManager();
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
- $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
$this->assertEquals($dateTimeGet->getTimestamp(), $dateTimeSet->getTimestamp());
}
@@ -594,7 +649,7 @@ class ManagerTest extends TestCase {
$dateTimeSet = new \DateTime('today');
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
- $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
$this->assertEquals($dateTimeGet, $dateTimeSet);
}
@@ -611,7 +666,7 @@ class ManagerTest extends TestCase {
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
$manager->deleteReadMarksFromUser($user);
- $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
$this->assertNull($dateTimeGet);
}
@@ -628,7 +683,7 @@ class ManagerTest extends TestCase {
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
$manager->deleteReadMarksOnObject('robot', '36');
- $dateTimeGet = $manager->getReadMark('robot', '36', $user);
+ $dateTimeGet = $manager->getReadMark('robot', '36', $user);
$this->assertNull($dateTimeGet);
}
@@ -643,8 +698,12 @@ class ManagerTest extends TestCase {
->method('handle');
$manager = $this->getManager();
- $manager->registerEventHandler(function () use ($handler1) {return $handler1; });
- $manager->registerEventHandler(function () use ($handler2) {return $handler2; });
+ $manager->registerEventHandler(function () use ($handler1) {
+ return $handler1;
+ });
+ $manager->registerEventHandler(function () use ($handler2) {
+ return $handler2;
+ });
$comment = new Comment();
$comment
@@ -667,11 +726,11 @@ class ManagerTest extends TestCase {
public function testResolveDisplayName() {
$manager = $this->getManager();
- $planetClosure = function($name) {
+ $planetClosure = function ($name) {
return ucfirst($name);
};
- $galaxyClosure = function($name) {
+ $galaxyClosure = function ($name) {
return strtoupper($name);
};
@@ -688,7 +747,7 @@ class ManagerTest extends TestCase {
public function testRegisterResolverDuplicate() {
$manager = $this->getManager();
- $planetClosure = function($name) {
+ $planetClosure = function ($name) {
return ucfirst($name);
};
$manager->registerDisplayNameResolver('planet', $planetClosure);
@@ -701,7 +760,7 @@ class ManagerTest extends TestCase {
public function testRegisterResolverInvalidType() {
$manager = $this->getManager();
- $planetClosure = function($name) {
+ $planetClosure = function ($name) {
return ucfirst($name);
};
$manager->registerDisplayNameResolver(1337, $planetClosure);
@@ -713,7 +772,7 @@ class ManagerTest extends TestCase {
public function testResolveDisplayNameUnregisteredType() {
$manager = $this->getManager();
- $planetClosure = function($name) {
+ $planetClosure = function ($name) {
return ucfirst($name);
};
@@ -724,7 +783,9 @@ class ManagerTest extends TestCase {
public function testResolveDisplayNameDirtyResolver() {
$manager = $this->getManager();
- $planetClosure = function() { return null; };
+ $planetClosure = function () {
+ return null;
+ };
$manager->registerDisplayNameResolver('planet', $planetClosure);
$this->assertTrue(is_string($manager->resolveDisplayName('planet', 'neptune')));
@@ -736,7 +797,9 @@ class ManagerTest extends TestCase {
public function testResolveDisplayNameInvalidType() {
$manager = $this->getManager();
- $planetClosure = function() { return null; };
+ $planetClosure = function () {
+ return null;
+ };
$manager->registerDisplayNameResolver('planet', $planetClosure);
$this->assertTrue(is_string($manager->resolveDisplayName(1337, 'neptune')));
diff --git a/tests/lib/DB/QueryBuilder/QueryBuilderTest.php b/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
index 22808f586ef..150c772b26c 100644
--- a/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
+++ b/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
@@ -1200,7 +1200,7 @@ class QueryBuilderTest extends \Test\TestCase {
public function dataGetColumnName() {
return [
['column', '', '`column`'],
- ['column', 'a', 'a.`column`'],
+ ['column', 'a', '`a`.`column`'],
];
}
diff --git a/tests/lib/DB/QueryBuilder/QuoteHelperTest.php b/tests/lib/DB/QueryBuilder/QuoteHelperTest.php
index b83d9eed2df..3c1abd72f66 100644
--- a/tests/lib/DB/QueryBuilder/QuoteHelperTest.php
+++ b/tests/lib/DB/QueryBuilder/QuoteHelperTest.php
@@ -65,7 +65,7 @@ class QuoteHelperTest extends \Test\TestCase {
public function dataQuoteColumnNames() {
return [
// Single case
- ['d.column', 'd.`column`'],
+ ['d.column', '`d`.`column`'],
['column', '`column`'],
[new Literal('literal'), 'literal'],
[new Literal(1), '1'],