Merge pull request #20775 from owncloud/comments-manager

add icommentsmanger and icomment implementation
This commit is contained in:
Thomas Müller 2015-12-09 17:44:40 +01:00
commit ea7fe672e8
15 changed files with 1756 additions and 7 deletions

View File

@ -814,6 +814,19 @@ $CONFIG = array(
*/
'enforce_home_folder_naming_rule' => true,
/**
* Comments
*
* Global settings for the Comments infrastructure
*/
/**
* Replaces the default Comments Manager Factory. This can be utilized if an
* own or 3rdParty CommentsManager should be used that for instance uses the
* filesystem instead of the database to keep the comments.
*/
'comments.managerFactory' => '\OC\Comments\ManagerFactory',
/**
* Maintenance
*

View File

@ -0,0 +1,357 @@
<?php
namespace OC\Comments;
use OCP\Comments\IComment;
use OCP\Comments\IllegalIDChangeException;
class Comment implements IComment {
protected $data = [
'id' => '',
'parentId' => '0',
'topmostParentId' => '0',
'childrenCount' => '0',
'message' => '',
'verb' => '',
'actorType' => '',
'actorId' => '',
'objectType' => '',
'objectId' => '',
'creationDT' => null,
'latestChildDT' => null,
];
/**
* Comment constructor.
*
* @param [] $data optional, array with keys according to column names from
* the comments database scheme
*/
public function __construct(array $data = null) {
if(is_array($data)) {
$this->fromArray($data);
}
}
/**
* returns the ID of the comment
*
* It may return an empty string, if the comment was not stored.
* It is expected that the concrete Comment implementation gives an ID
* by itself (e.g. after saving).
*
* @return string
* @since 9.0.0
*/
public function getId() {
return $this->data['id'];
}
/**
* sets the ID of the comment and returns itself
*
* It is only allowed to set the ID only, if the current id is an empty
* string (which means it is not stored in a database, storage or whatever
* the concrete implementation does), or vice versa. Changing a given ID is
* not permitted and must result in an IllegalIDChangeException.
*
* @param string $id
* @return IComment
* @throws IllegalIDChangeException
* @since 9.0.0
*/
public function setId($id) {
if(!is_string($id)) {
throw new \InvalidArgumentException('String expected.');
}
$id = trim($id);
if($this->data['id'] === '' || ($this->data['id'] !== '' && $id === '')) {
$this->data['id'] = $id;
return $this;
}
throw new IllegalIDChangeException('Not allowed to assign a new ID to an already saved comment.');
}
/**
* returns the parent ID of the comment
*
* @return string
* @since 9.0.0
*/
public function getParentId() {
return $this->data['parentId'];
}
/**
* sets the parent ID and returns itself
*
* @param string $parentId
* @return IComment
* @since 9.0.0
*/
public function setParentId($parentId) {
if(!is_string($parentId)) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['parentId'] = trim($parentId);
return $this;
}
/**
* returns the topmost parent ID of the comment
*
* @return string
* @since 9.0.0
*/
public function getTopmostParentId() {
return $this->data['topmostParentId'];
}
/**
* sets the topmost parent ID and returns itself
*
* @param string $id
* @return IComment
* @since 9.0.0
*/
public function setTopmostParentId($id) {
if(!is_string($id)) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['topmostParentId'] = trim($id);
return $this;
}
/**
* returns the number of children
*
* @return int
* @since 9.0.0
*/
public function getChildrenCount() {
return $this->data['childrenCount'];
}
/**
* sets the number of children
*
* @param int $count
* @return IComment
* @since 9.0.0
*/
public function setChildrenCount($count) {
if(!is_int($count)) {
throw new \InvalidArgumentException('Integer expected.');
}
$this->data['childrenCount'] = $count;
return $this;
}
/**
* returns the message of the comment
*
* @return string
* @since 9.0.0
*/
public function getMessage() {
return $this->data['message'];
}
/**
* sets the message of the comment and returns itself
*
* @param string $message
* @return IComment
* @since 9.0.0
*/
public function setMessage($message) {
if(!is_string($message)) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['message'] = trim($message);
return $this;
}
/**
* returns the verb of the comment
*
* @return string
* @since 9.0.0
*/
public function getVerb() {
return $this->data['verb'];
}
/**
* sets the verb of the comment, e.g. 'comment' or 'like'
*
* @param string $verb
* @return IComment
* @since 9.0.0
*/
public function setVerb($verb) {
if(!is_string($verb) || !trim($verb)) {
throw new \InvalidArgumentException('Non-empty String expected.');
}
$this->data['verb'] = trim($verb);
return $this;
}
/**
* returns the actor type
*
* @return string
* @since 9.0.0
*/
public function getActorType() {
return $this->data['actorType'];
}
/**
* returns the actor ID
*
* @return string
* @since 9.0.0
*/
public function getActorId() {
return $this->data['actorId'];
}
/**
* sets (overwrites) the actor type and id
*
* @param string $actorType e.g. 'user'
* @param string $actorId e.g. 'zombie234'
* @return IComment
* @since 9.0.0
*/
public function setActor($actorType, $actorId) {
if(
!is_string($actorType) || !trim($actorType)
|| !is_string($actorId) || !trim($actorId)
) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['actorType'] = trim($actorType);
$this->data['actorId'] = trim($actorId);
return $this;
}
/**
* returns the creation date of the comment.
*
* If not explicitly set, it shall default to the time of initialization.
*
* @return \DateTime
* @since 9.0.0
*/
public function getCreationDateTime() {
return $this->data['creationDT'];
}
/**
* sets the creation date of the comment and returns itself
*
* @param \DateTime $timestamp
* @return IComment
* @since 9.0.0
*/
public function setCreationDateTime(\DateTime $timestamp) {
$this->data['creationDT'] = $timestamp;
return $this;
}
/**
* returns the timestamp of the most recent child
*
* @return int
* @since 9.0.0
*/
public function getLatestChildDateTime() {
return $this->data['latestChildDT'];
}
/**
* sets the date of the most recent child
*
* @param \DateTime $dateTime
* @return IComment
* @since 9.0.0
*/
public function setLatestChildDateTime(\DateTime $dateTime = null) {
$this->data['latestChildDT'] = $dateTime;
return $this;
}
/**
* returns the object type the comment is attached to
*
* @return string
* @since 9.0.0
*/
public function getObjectType() {
return $this->data['objectType'];
}
/**
* returns the object id the comment is attached to
*
* @return string
* @since 9.0.0
*/
public function getObjectId() {
return $this->data['objectId'];
}
/**
* sets (overwrites) the object of the comment
*
* @param string $objectType e.g. 'file'
* @param string $objectId e.g. '16435'
* @return IComment
* @since 9.0.0
*/
public function setObject($objectType, $objectId) {
if(
!is_string($objectType) || !trim($objectType)
|| !is_string($objectId) || !trim($objectId)
) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['objectType'] = trim($objectType);
$this->data['objectId'] = trim($objectId);
return $this;
}
/**
* sets the comment data based on an array with keys as taken from the
* database.
*
* @param [] $data
* @return IComment
*/
protected function fromArray($data) {
foreach(array_keys($data) as $key) {
// translate DB keys to internal setter names
$setter = 'set' . str_replace('_', '', ucwords($key,'_'));
$setter = str_replace('Timestamp', 'DateTime', $setter);
if(method_exists($this, $setter)) {
$this->$setter($data[$key]);
}
}
foreach(['actor', 'object'] as $role) {
if(isset($data[$role . '_type']) && isset($data[$role . '_id'])) {
$setter = 'set' . ucfirst($role);
$this->$setter($data[$role . '_type'], $data[$role . '_id']);
}
}
return $this;
}
}

View File

@ -0,0 +1,549 @@
<?php
namespace OC\Comments;
use Doctrine\DBAL\Exception\DriverException;
use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager;
use OCP\Comments\NotFoundException;
use OCP\IDBConnection;
use OCP\ILogger;
class Manager implements ICommentsManager {
/** @var IDBConnection */
protected $dbConn;
/** @var ILogger */
protected $logger;
/** @var IComment[] */
protected $commentsCache = [];
public function __construct(
IDBConnection $dbConn,
ILogger $logger
) {
$this->dbConn = $dbConn;
$this->logger = $logger;
}
/**
* converts data base data into PHP native, proper types as defined by
* IComment interface.
*
* @param array $data
* @return array
*/
protected function normalizeDatabaseData(array $data) {
$data['id'] = strval($data['id']);
$data['parent_id'] = strval($data['parent_id']);
$data['topmost_parent_id'] = strval($data['topmost_parent_id']);
$data['creation_timestamp'] = new \DateTime($data['creation_timestamp']);
$data['latest_child_timestamp'] = new \DateTime($data['latest_child_timestamp']);
$data['children_count'] = intval($data['children_count']);
return $data;
}
/**
* prepares a comment for an insert or update operation after making sure
* all necessary fields have a value assigned.
*
* @param IComment $comment
* @return IComment returns the same updated IComment instance as provided
* by parameter for convenience
* @throws \UnexpectedValueException
*/
protected function prepareCommentForDatabaseWrite(IComment $comment) {
if( !$comment->getActorType()
|| !$comment->getActorId()
|| !$comment->getObjectType()
|| !$comment->getObjectId()
|| !$comment->getVerb()
) {
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
}
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())) {
$comment->setCreationDateTime(new \DateTime());
}
if($comment->getParentId() !== '0') {
$comment->setTopmostParentId($this->determineTopmostParentId($comment->getParentId()));
} else {
$comment->setTopmostParentId('0');
}
$this->cache($comment);
return $comment;
}
/**
* returns the topmost parent id of a given comment identified by ID
*
* @param string $id
* @return string
* @throws NotFoundException
*/
protected function determineTopmostParentId($id) {
$comment = $this->get($id);
if($comment->getParentId() === '0') {
return $comment->getId();
} else {
return $this->determineTopmostParentId($comment->getId());
}
}
/**
* updates child information of a comment
*
* @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);
$resultStatement = $query->execute();
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
$resultStatement->closeCursor();
$children = intval($data[0]);
$comment = $this->get($id);
$comment->setChildrenCount($children);
$comment->setLatestChildDateTime($cDateTime);
$this->save($comment);
}
/**
* Tests whether actor or object type and id parameters are acceptable.
* Throws exception if not.
*
* @param string $role
* @param string $type
* @param string $id
* @throws \InvalidArgumentException
*/
protected function checkRoleParameters($role, $type, $id) {
if(
!is_string($type) || empty($type)
|| !is_string($id) || empty($id)
) {
throw new \InvalidArgumentException($role . ' parameters must be string and not empty');
}
}
/**
* run-time caches a comment
*
* @param IComment $comment
*/
protected function cache(IComment $comment) {
$id = $comment->getId();
if(empty($id)) {
return;
}
$this->commentsCache[strval($id)] = $comment;
}
/**
* removes an entry from the comments run time cache
*
* @param mixed $id the comment's id
*/
protected function uncache($id) {
$id = strval($id);
if (isset($this->commentsCache[$id])) {
unset($this->commentsCache[$id]);
}
}
/**
* returns a comment instance
*
* @param string $id the ID of the comment
* @return IComment
* @throws NotFoundException
* @throws \InvalidArgumentException
* @since 9.0.0
*/
public function get($id) {
if(intval($id) === 0) {
throw new \InvalidArgumentException('IDs must be translatable to a number in this implementation.');
}
if(isset($this->commentsCache[$id])) {
return $this->commentsCache[$id];
}
$qb = $this->dbConn->getQueryBuilder();
$resultStatement = $qb->select('*')
->from('comments')
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter('id', $id, \PDO::PARAM_INT)
->execute();
$data = $resultStatement->fetch();
$resultStatement->closeCursor();
if(!$data) {
throw new NotFoundException();
}
$comment = new Comment($this->normalizeDatabaseData($data));
$this->cache($comment);
return $comment;
}
/**
* returns the comment specified by the id and all it's child comments.
* At this point of time, we do only support one level depth.
*
* @param string $id
* @param int $limit max number of entries to return, 0 returns all
* @param int $offset the start entry
* @return array
* @since 9.0.0
*
* The return array looks like this
* [
* 'comment' => IComment, // root comment
* 'replies' =>
* [
* 0 =>
* [
* 'comment' => IComment,
* 'replies' => []
* ]
* 1 =>
* [
* 'comment' => IComment,
* 'replies'=> []
* ],
*
* ]
* ]
*/
public function getTree($id, $limit = 0, $offset = 0) {
$tree = [];
$tree['comment'] = $this->get($id);
$tree['replies'] = [];
$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);
if($limit > 0) {
$query->setMaxResults($limit);
}
if($offset > 0) {
$query->setFirstResult($offset);
}
$resultStatement = $query->execute();
while($data = $resultStatement->fetch()) {
$comment = new Comment($this->normalizeDatabaseData($data));
$this->cache($comment);
$tree['replies'][] = [
'comment' => $comment,
'replies' => []
];
}
$resultStatement->closeCursor();
return $tree;
}
/**
* returns comments for a specific object (e.g. a file).
*
* The sort order is always newest to oldest.
*
* @param string $objectType the object type, e.g. 'files'
* @param string $objectId the id of the object
* @param int $limit optional, number of maximum comments to be returned. if
* not specified, all comments are returned.
* @param int $offset optional, starting point
* @param \DateTime $notOlderThan optional, timestamp of the oldest comments
* that may be returned
* @return IComment[]
* @since 9.0.0
*/
public function getForObject(
$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) {
$query->setMaxResults($limit);
}
if($offset > 0) {
$query->setFirstResult($offset);
}
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()) {
$comment = new Comment($this->normalizeDatabaseData($data));
$this->cache($comment);
$comments[] = $comment;
}
$resultStatement->closeCursor();
return $comments;
}
/**
* @param $objectType string the object type, e.g. 'files'
* @param $objectId string the id of the object
* @return Int
* @since 9.0.0
*/
public function getNumberOfCommentsForObject($objectType, $objectId) {
$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);
$resultStatement = $query->execute();
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
$resultStatement->closeCursor();
return intval($data[0]);
}
/**
* 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).
*
* @param string $actorType the actor type (e.g. 'user')
* @param string $actorId a user id
* @param string $objectType the object type the comment is attached to
* @param string $objectId the object id the comment is attached to
* @return IComment
* @since 9.0.0
*/
public function create($actorType, $actorId, $objectType, $objectId) {
$comment = new Comment();
$comment
->setActor($actorType, $actorId)
->setObject($objectType, $objectId);
return $comment;
}
/**
* permanently deletes the comment specified by the ID
*
* When the comment has child comments, their parent ID will be changed to
* the parent ID of the item that is to be deleted.
*
* @param string $id
* @return bool
* @throws \InvalidArgumentException
* @since 9.0.0
*/
public function delete($id) {
if(!is_string($id)) {
throw new \InvalidArgumentException('Parameter must be string');
}
$qb = $this->dbConn->getQueryBuilder();
$query = $qb->delete('comments')
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter('id', $id);
try {
$affectedRows = $query->execute();
$this->uncache($id);
} catch (DriverException $e) {
$this->logger->logException($e, ['app' => 'core_comments']);
return false;
}
return ($affectedRows > 0);
}
/**
* saves the comment permanently and returns it
*
* if the supplied comment has an empty ID, a new entry comment will be
* saved and the instance updated with the new ID.
*
* Otherwise, an existing comment will be updated.
*
* Throws NotFoundException when a comment that is to be updated does not
* exist anymore at this point of time.
*
* @param IComment $comment
* @return bool
* @throws NotFoundException
* @since 9.0.0
*/
public function save(IComment $comment) {
if($this->prepareCommentForDatabaseWrite($comment)->getId() === '') {
$result = $this->insert($comment);
} else {
$result = $this->update($comment);
}
if($result && !!$comment->getParentId()) {
$this->updateChildrenInformation(
$comment->getParentId(),
$comment->getCreationDateTime()
);
$this->cache($comment);
}
return $result;
}
/**
* inserts the provided comment in the database
*
* @param IComment $comment
* @return bool
*/
protected function insert(IComment &$comment) {
$qb = $this->dbConn->getQueryBuilder();
$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()),
])
->execute();
if ($affectedRows > 0) {
$comment->setId(strval($qb->getLastInsertId()));
}
return $affectedRows > 0;
}
/**
* updates a Comment data row
*
* @param IComment $comment
* @return bool
* @throws NotFoundException
*/
protected function update(IComment $comment) {
$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()))
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter('id', $comment->getId())
->execute();
if($affectedRows === 0) {
throw new NotFoundException('Comment to update does ceased to exist');
}
return $affectedRows > 0;
}
/**
* removes references to specific actor (e.g. on user delete) of a comment.
* The comment itself must not get lost/deleted.
*
* @param string $actorType the actor type (e.g. 'user')
* @param string $actorId a user id
* @return boolean
* @since 9.0.0
*/
public function deleteReferencesOfActor($actorType, $actorId) {
$this->checkRoleParameters('Actor', $actorType, $actorId);
$qb = $this->dbConn->getQueryBuilder();
$affectedRows = $qb
->update('comments')
->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)
->setParameter('id', $actorId)
->execute();
$this->commentsCache = [];
return is_int($affectedRows);
}
/**
* deletes all comments made of a specific object (e.g. on file delete)
*
* @param string $objectType the object type (e.g. 'file')
* @param string $objectId e.g. the file id
* @return boolean
* @since 9.0.0
*/
public function deleteCommentsAtObject($objectType, $objectId) {
$this->checkRoleParameters('Object', $objectType, $objectId);
$qb = $this->dbConn->getQueryBuilder();
$affectedRows = $qb
->delete('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)
->execute();
$this->commentsCache = [];
return is_int($affectedRows);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace OC\Comments;
use OCP\Comments\ICommentsManager;
use OCP\Comments\ICommentsManagerFactory;
class ManagerFactory implements ICommentsManagerFactory {
/**
* creates and returns an instance of the ICommentsManager
*
* @return ICommentsManager
* @since 9.0.0
*/
public function getManager() {
return new Manager(
\OC::$server->getDatabaseConnection(),
\OC::$server->getLogger()
);
}
}

View File

@ -528,6 +528,13 @@ class Server extends SimpleContainer implements IServerContainer {
});
return $manager;
});
$this->registerService('CommentsManager', function(Server $c) {
$config = $c->getConfig();
$factoryClass = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
/** @var \OCP\Comments\ICommentsManagerFactory $factory */
$factory = new $factoryClass();
return $factory->getManager();
});
$this->registerService('EventDispatcher', function() {
return new EventDispatcher();
});
@ -1121,6 +1128,13 @@ class Server extends SimpleContainer implements IServerContainer {
return $this->query('NotificationManager');
}
/**
* @return \OCP\Comments\ICommentsManager
*/
public function getCommentsManager() {
return $this->query('CommentsManager');
}
/**
* @return \OC\IntegrityCheck\Checker
*/

View File

@ -189,6 +189,8 @@ class User implements IUser {
// Delete the users entry in the storage table
\OC\Files\Cache\Storage::remove('home::' . $this->uid);
\OC::$server->getCommentsManager()->deleteReferencesOfActor('user', $this->uid);
}
if ($this->emitter) {

View File

@ -5,7 +5,7 @@ namespace OCP\Comments;
/**
* Interface IComment
*
* This class represents a comment and offers methods for modification.
* This class represents a comment
*
* @package OCP\Comments
* @since 9.0.0
@ -49,13 +49,30 @@ interface IComment {
/**
* sets the parent ID and returns itself
*
* @param string $parentId
* @return IComment
* @since 9.0.0
*/
public function setParentId($parentId);
/**
* returns the topmost parent ID of the comment
*
* @return string
* @since 9.0.0
*/
public function getTopmostParentId();
/**
* sets the topmost parent ID and returns itself
*
* @param string $id
* @return IComment
* @since 9.0.0
*/
public function setTopmostParentId($id);
/**
* returns the number of children
*

View File

@ -12,6 +12,17 @@ namespace OCP\Comments;
*/
interface ICommentsManager {
/**
* @const DELETED_USER type and id for a user that has been deleted
* @see deleteReferencesOfActor
* @since 9.0.0
*
* To be used as replacement for user type actors in deleteReferencesOfActor().
*
* User interfaces shall show "Deleted user" as display name, if needed.
*/
const DELETED_USER = 'deleted_user';
/**
* returns a comment instance
*
@ -28,7 +39,7 @@ interface ICommentsManager {
* @param string $id
* @param int $limit max number of entries to return, 0 returns all
* @param int $offset the start entry
* @return []
* @return array
* @since 9.0.0
*
* The return array looks like this
@ -73,7 +84,6 @@ interface ICommentsManager {
* @param \DateTime $notOlderThan optional, timestamp of the oldest comments
* that may be returned
* @return IComment[]
* @throws NotFoundException in case the requested type or id is not present
* @since 9.0.0
*/
public function getForObject(
@ -88,7 +98,6 @@ interface ICommentsManager {
* @param $objectType string the object type, e.g. 'files'
* @param $objectId string the id of the object
* @return Int
* @throws NotFoundException in case the requested type or id is not present
* @since 9.0.0
*/
public function getNumberOfCommentsForObject($objectType, $objectId);
@ -130,17 +139,20 @@ interface ICommentsManager {
* Throws NotFoundException when a comment that is to be updated does not
* exist anymore at this point of time.
*
* @param IComment
* @param IComment $comment
* @return bool
* @throws NotFoundException
* @since 9.0.0
*/
public function save(&$comment);
public function save(IComment $comment);
/**
* removes references to specific actor (e.g. on user delete) of a comment.
* The comment itself must not get lost/deleted.
*
* A 'user' type actor (type and id) should get replaced by the
* value of the DELETED_USER constant of this interface.
*
* @param string $actorType the actor type (e.g. 'user')
* @param string $actorId a user id
* @return boolean

View File

@ -0,0 +1,23 @@
<?php
namespace OCP\Comments;
/**
* Interface ICommentsManagerFactory
*
* This class is responsible for instantiating and returning an ICommentsManager
* instance.
*
* @package OCP\Comments
* @since 9.0.0
*/
interface ICommentsManagerFactory {
/**
* creates and returns an instance of the ICommentsManager
*
* @return ICommentsManager
* @since 9.0.0
*/
public function getManager();
}

View File

@ -471,6 +471,12 @@ interface IServerContainer {
*/
public function getNotificationManager();
/**
* @return \OCP\Comments\ICommentsManager
* @since 9.0.0
*/
public function getCommentsManager();
/**
* Returns the system-tag manager
*

View File

@ -0,0 +1,110 @@
<?php
namespace Test\Comments;
use Test\TestCase;
class Test_Comments_Comment extends TestCase
{
public function testSettersValidInput() {
$comment = new \OC\Comments\Comment();
$id = 'comment23';
$parentId = 'comment11.5';
$childrenCount = 6;
$message = 'I like to comment comment';
$verb = 'comment';
$actor = ['type' => 'user', 'id' => 'alice'];
$creationDT = new \DateTime();
$latestChildDT = new \DateTime('yesterday');
$object = ['type' => 'file', 'id' => 'file64'];
$comment
->setId($id)
->setParentId($parentId)
->setChildrenCount($childrenCount)
->setMessage($message)
->setVerb($verb)
->setActor($actor['type'], $actor['id'])
->setCreationDateTime($creationDT)
->setLatestChildDateTime($latestChildDT)
->setObject($object['type'], $object['id']);
$this->assertSame($id, $comment->getId());
$this->assertSame($parentId, $comment->getParentId());
$this->assertSame($childrenCount, $comment->getChildrenCount());
$this->assertSame($message, $comment->getMessage());
$this->assertSame($verb, $comment->getVerb());
$this->assertSame($actor['type'], $comment->getActorType());
$this->assertSame($actor['id'], $comment->getActorId());
$this->assertSame($creationDT, $comment->getCreationDateTime());
$this->assertSame($latestChildDT, $comment->getLatestChildDateTime());
$this->assertSame($object['type'], $comment->getObjectType());
$this->assertSame($object['id'], $comment->getObjectId());
}
/**
* @expectedException \OCP\Comments\IllegalIDChangeException
*/
public function testSetIdIllegalInput() {
$comment = new \OC\Comments\Comment();
$comment->setId('c23');
$comment->setId('c17');
}
public function testResetId() {
$comment = new \OC\Comments\Comment();
$comment->setId('c23');
$comment->setId('');
}
public function simpleSetterProvider() {
return [
['Id', true],
['ParentId', true],
['Message', true],
['Verb', true],
['Verb', ''],
['ChildrenCount', true],
];
}
/**
* @dataProvider simpleSetterProvider
* @expectedException \InvalidArgumentException
*/
public function testSimpleSetterInvalidInput($field, $input) {
$comment = new \OC\Comments\Comment();
$setter = 'set' . $field;
$comment->$setter($input);
}
public function roleSetterProvider() {
return [
['Actor', true, true],
['Actor', 'user', true],
['Actor', true, 'alice'],
['Actor', ' ', ' '],
['Object', true, true],
['Object', 'file', true],
['Object', true, 'file64'],
['Object', ' ', ' '],
];
}
/**
* @dataProvider roleSetterProvider
* @expectedException \InvalidArgumentException
*/
public function testSetRoleInvalidInput($role, $type, $id){
$comment = new \OC\Comments\Comment();
$setter = 'set' . $role;
$comment->$setter($type, $id);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Test\Comments;
/**
* Class FakeFactory
*/
class FakeFactory implements \OCP\Comments\ICommentsManagerFactory {
public function getManager() {
return new FakeManager();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Test\Comments;
/**
* Class FakeManager
*/
class FakeManager implements \OCP\Comments\ICommentsManager {
public function get($id) {}
public function getTree($id, $limit = 0, $offset = 0) {}
public function getForObject(
$objectType,
$objectId,
$limit = 0,
$offset = 0,
\DateTime $notOlderThan = null
) {}
public function getNumberOfCommentsForObject($objectType, $objectId) {}
public function create($actorType, $actorId, $objectType, $objectId) {}
public function delete($id) {}
public function save(\OCP\Comments\IComment $comment) {}
public function deleteReferencesOfActor($actorType, $actorId) {}
public function deleteCommentsAtObject($objectType, $objectId) {}
}

View File

@ -0,0 +1,564 @@
<?php
namespace Test\Comments;
use OCP\Comments\ICommentsManager;
use Test\TestCase;
/**
* Class Test_Comments_Manager
*
* @group DB
*/
class Test_Comments_Manager extends TestCase
{
public function setUp() {
parent::setUp();
$sql = \OC::$server->getDatabaseConnection()->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
\OC::$server->getDatabaseConnection()->prepare($sql)->execute();
}
protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null) {
if(is_null($creationDT)) {
$creationDT = new \DateTime();
}
if(is_null($latestChildDT)) {
$latestChildDT = new \DateTime('yesterday');
}
$qb = \OC::$server->getDatabaseConnection()->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('user'),
'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('file'),
'object_id' => $qb->createNamedParameter('file64'),
])
->execute();
return $qb->getLastInsertId();
}
protected function getManager() {
$factory = new \OC\Comments\ManagerFactory();
return $factory->getManager();
}
/**
* @expectedException \OCP\Comments\NotFoundException
*/
public function testGetCommentNotFound() {
$manager = $this->getManager();
$manager->get('22');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testGetCommentNotFoundInvalidInput() {
$manager = $this->getManager();
$manager->get('unexisting22');
}
public function testGetComment() {
$manager = $this->getManager();
$creationDT = new \DateTime();
$latestChildDT = new \DateTime('yesterday');
$qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
$qb
->insert('comments')
->values([
'parent_id' => $qb->createNamedParameter('2'),
'topmost_parent_id' => $qb->createNamedParameter('1'),
'children_count' => $qb->createNamedParameter(2),
'actor_type' => $qb->createNamedParameter('user'),
'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('file'),
'object_id' => $qb->createNamedParameter('file64'),
])
->execute();
$id = strval($qb->getLastInsertId());
$comment = $manager->get($id);
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$this->assertSame($comment->getId(), $id);
$this->assertSame($comment->getParentId(), '2');
$this->assertSame($comment->getTopmostParentId(), '1');
$this->assertSame($comment->getChildrenCount(), 2);
$this->assertSame($comment->getActorType(), 'user');
$this->assertSame($comment->getActorId(), 'alice');
$this->assertSame($comment->getMessage(), 'nice one');
$this->assertSame($comment->getVerb(), 'comment');
$this->assertSame($comment->getObjectType(), 'file');
$this->assertSame($comment->getObjectId(), 'file64');
$this->assertEquals($comment->getCreationDateTime(), $creationDT);
$this->assertEquals($comment->getLatestChildDateTime(), $latestChildDT);
}
/**
* @expectedException \OCP\Comments\NotFoundException
*/
public function testGetTreeNotFound() {
$manager = $this->getManager();
$manager->getTree('22');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testGetTreeNotFoundInvalidIpnut() {
$manager = $this->getManager();
$manager->getTree('unexisting22');
}
public function testGetTree() {
$headId = $this->addDatabaseEntry(0, 0);
$this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
$this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
$id = $this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
$manager = $this->getManager();
$tree = $manager->getTree($headId);
// Verifying the root comment
$this->assertTrue(isset($tree['comment']));
$this->assertTrue($tree['comment'] instanceof \OCP\Comments\IComment);
$this->assertSame($tree['comment']->getId(), strval($headId));
$this->assertTrue(isset($tree['replies']));
$this->assertSame(count($tree['replies']), 3);
// one level deep
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);
$id--;
}
}
public function testGetTreeNoReplies() {
$id = $this->addDatabaseEntry(0, 0);
$manager = $this->getManager();
$tree = $manager->getTree($id);
// Verifying the root comment
$this->assertTrue(isset($tree['comment']));
$this->assertTrue($tree['comment'] instanceof \OCP\Comments\IComment);
$this->assertSame($tree['comment']->getId(), strval($id));
$this->assertTrue(isset($tree['replies']));
$this->assertSame(count($tree['replies']), 0);
// one level deep
foreach($tree['replies'] as $reply) {
throw new \Exception('This ain`t happen');
}
}
public function testGetTreeWithLimitAndOffset() {
$headId = $this->addDatabaseEntry(0, 0);
$this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
$this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
$this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
$idToVerify = $this->addDatabaseEntry($headId, $headId, new \DateTime());
$manager = $this->getManager();
for ($offset = 0; $offset < 3; $offset += 2) {
$tree = $manager->getTree(strval($headId), 2, $offset);
// Verifying the root comment
$this->assertTrue(isset($tree['comment']));
$this->assertTrue($tree['comment'] instanceof \OCP\Comments\IComment);
$this->assertSame($tree['comment']->getId(), strval($headId));
$this->assertTrue(isset($tree['replies']));
$this->assertSame(count($tree['replies']), 2);
// one level deep
foreach ($tree['replies'] as $reply) {
$this->assertTrue($reply['comment'] instanceof \OCP\Comments\IComment);
$this->assertSame($reply['comment']->getId(), strval($idToVerify));
$this->assertSame(count($reply['replies']), 0);
$idToVerify--;
}
}
}
public function testGetForObject() {
$this->addDatabaseEntry(0, 0);
$manager = $this->getManager();
$comments = $manager->getForObject('file', 'file64');
$this->assertTrue(is_array($comments));
$this->assertSame(count($comments), 1);
$this->assertTrue($comments[0] instanceof \OCP\Comments\IComment);
$this->assertSame($comments[0]->getMessage(), 'nice one');
}
public function testGetForObjectWithLimitAndOffset() {
$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
$this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
$this->addDatabaseEntry(1, 1, new \DateTime('-4 hours'));
$this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
$this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
$this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
$idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
$manager = $this->getManager();
$offset = 0;
do {
$comments = $manager->getForObject('file', 'file64', 3, $offset);
$this->assertTrue(is_array($comments));
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);
}
public function testGetForObjectWithDateTimeConstraint() {
$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
$this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
$id1 = $this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
$id2 = $this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
$manager = $this->getManager();
$comments = $manager->getForObject('file', 'file64', 0, 0, new \DateTime('-4 hours'));
$this->assertSame(count($comments), 2);
$this->assertSame($comments[0]->getId(), strval($id2));
$this->assertSame($comments[1]->getId(), strval($id1));
}
public function testGetForObjectWithLimitAndOffsetAndDateTimeConstraint() {
$this->addDatabaseEntry(0, 0, new \DateTime('-7 hours'));
$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
$this->addDatabaseEntry(1, 1, new \DateTime('-5 hours'));
$this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
$this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
$this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
$idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
$manager = $this->getManager();
$offset = 0;
do {
$comments = $manager->getForObject('file', 'file64', 3, $offset, new \DateTime('-4 hours'));
$this->assertTrue(is_array($comments));
foreach($comments as $comment) {
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$this->assertSame($comment->getMessage(), 'nice one');
$this->assertSame($comment->getId(), strval($idToVerify));
$this->assertTrue(intval($comment->getId()) >= 4);
$idToVerify--;
}
$offset += 3;
} while(count($comments) > 0);
}
public function testGetNumberOfCommentsForObject() {
for($i = 1; $i < 5; $i++) {
$this->addDatabaseEntry(0, 0);
}
$manager = $this->getManager();
$amount = $manager->getNumberOfCommentsForObject('untype', '00');
$this->assertSame($amount, 0);
$amount = $manager->getNumberOfCommentsForObject('file', 'file64');
$this->assertSame($amount, 4);
}
public function invalidCreateArgsProvider() {
return [
['', 'aId-1', 'oType-1', 'oId-1'],
['aType-1', '', 'oType-1', 'oId-1'],
['aType-1', 'aId-1', '', 'oId-1'],
['aType-1', 'aId-1', 'oType-1', ''],
[1, 'aId-1', 'oType-1', 'oId-1'],
['aType-1', 1, 'oType-1', 'oId-1'],
['aType-1', 'aId-1', 1, 'oId-1'],
['aType-1', 'aId-1', 'oType-1', 1],
];
}
/**
* @dataProvider invalidCreateArgsProvider
* @expectedException \InvalidArgumentException
*/
public function testCreateCommentInvalidArguments($aType, $aId, $oType, $oId) {
$manager = $this->getManager();
$manager->create($aType, $aId, $oType, $oId);
}
public function testCreateComment() {
$actorType = 'bot';
$actorId = 'bob';
$objectType = 'weather';
$objectId = 'bielefeld';
$comment = $this->getManager()->create($actorType, $actorId, $objectType, $objectId);
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$this->assertSame($comment->getActorType(), $actorType);
$this->assertSame($comment->getActorId(), $actorId);
$this->assertSame($comment->getObjectType(), $objectType);
$this->assertSame($comment->getObjectId(), $objectId);
}
/**
* @expectedException \OCP\Comments\NotFoundException
*/
public function testDelete() {
$manager = $this->getManager();
$done = $manager->delete('404');
$this->assertFalse($done);
$done = $manager->delete('%');
$this->assertFalse($done);
$done = $manager->delete('');
$this->assertFalse($done);
$id = strval($this->addDatabaseEntry(0, 0));
$comment = $manager->get($id);
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
$done = $manager->delete($id);
$this->assertTrue($done);
$manager->get($id);
}
public function testSaveNew() {
$manager = $this->getManager();
$comment = new \OC\Comments\Comment();
$comment
->setActor('user', 'alice')
->setObject('file', 'file64')
->setMessage('very beautiful, I am impressed!')
->setVerb('comment');
$saveSuccessful = $manager->save($comment);
$this->assertTrue($saveSuccessful);
$this->assertTrue($comment->getId() !== '');
$this->assertTrue($comment->getId() !== '0');
$this->assertTrue(!is_null($comment->getCreationDateTime()));
$loadedComment = $manager->get($comment->getId());
$this->assertSame($comment->getMessage(), $loadedComment->getMessage());
$this->assertEquals($comment->getCreationDateTime(), $loadedComment->getCreationDateTime());
}
public function testSaveUpdate() {
$manager = $this->getManager();
$comment = new \OC\Comments\Comment();
$comment
->setActor('user', 'alice')
->setObject('file', 'file64')
->setMessage('very beautiful, I am impressed!')
->setVerb('comment');
$manager->save($comment);
$comment->setMessage('very beautiful, I am really so much impressed!');
$manager->save($comment);
$loadedComment = $manager->get($comment->getId());
$this->assertSame($comment->getMessage(), $loadedComment->getMessage());
}
/**
* @expectedException \OCP\Comments\NotFoundException
*/
public function testSaveUpdateException() {
$manager = $this->getManager();
$comment = new \OC\Comments\Comment();
$comment
->setActor('user', 'alice')
->setObject('file', 'file64')
->setMessage('very beautiful, I am impressed!')
->setVerb('comment');
$manager->save($comment);
$manager->delete($comment->getId());
$comment->setMessage('very beautiful, I am really so much impressed!');
$manager->save($comment);
}
/**
* @expectedException \UnexpectedValueException
*/
public function testSaveIncomplete() {
$manager = $this->getManager();
$comment = new \OC\Comments\Comment();
$comment->setMessage('from no one to nothing');
$manager->save($comment);
}
public function testSaveAsChild() {
$id = $this->addDatabaseEntry(0, 0);
$manager = $this->getManager();
for($i = 0; $i < 3; $i++) {
$comment = new \OC\Comments\Comment();
$comment
->setActor('user', 'alice')
->setObject('file', '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);
$this->assertSame($comment->getTopmostParentId(), strval($id));
$parentComment = $manager->get(strval($id));
$this->assertSame($parentComment->getChildrenCount(), $i + 1);
$this->assertEquals($parentComment->getLatestChildDateTime(), $comment->getCreationDateTime());
}
}
public function invalidActorArgsProvider() {
return
[
['', ''],
[1, 'alice'],
['user', 1],
];
}
/**
* @dataProvider invalidActorArgsProvider
* @expectedException \InvalidArgumentException
*/
public function testDeleteReferencesOfActorInvalidInput($type, $id) {
$manager = $this->getManager();
$manager->deleteReferencesOfActor($type, $id);
}
public function testDeleteReferencesOfActor() {
$ids = [];
$ids[] = $this->addDatabaseEntry(0, 0);
$ids[] = $this->addDatabaseEntry(0, 0);
$ids[] = $this->addDatabaseEntry(0, 0);
$manager = $this->getManager();
// just to make sure they are really set, with correct actor data
$comment = $manager->get(strval($ids[1]));
$this->assertSame($comment->getActorType(), 'user');
$this->assertSame($comment->getActorId(), 'alice');
$wasSuccessful = $manager->deleteReferencesOfActor('user', 'alice');
$this->assertTrue($wasSuccessful);
foreach($ids as $id) {
$comment = $manager->get(strval($id));
$this->assertSame($comment->getActorType(), ICommentsManager::DELETED_USER);
$this->assertSame($comment->getActorId(), ICommentsManager::DELETED_USER);
}
// actor info is gone from DB, but when database interaction is alright,
// we still expect to get true back
$wasSuccessful = $manager->deleteReferencesOfActor('user', 'alice');
$this->assertTrue($wasSuccessful);
}
public function testDeleteReferencesOfActorWithUserManagement() {
$user = \OC::$server->getUserManager()->createUser('xenia', '123456');
$this->assertTrue($user instanceof \OCP\IUser);
$manager = \OC::$server->getCommentsManager();
$comment = $manager->create('user', $user->getUID(), 'file', 'file64');
$comment
->setMessage('Most important comment I ever left on the Internet.')
->setVerb('comment');
$status = $manager->save($comment);
$this->assertTrue($status);
$commentID = $comment->getId();
$user->delete();
$comment = $manager->get($commentID);
$this->assertSame($comment->getActorType(), \OCP\Comments\ICommentsManager::DELETED_USER);
$this->assertSame($comment->getActorId(), \OCP\Comments\ICommentsManager::DELETED_USER);
}
public function invalidObjectArgsProvider() {
return
[
['', ''],
[1, 'file64'],
['file', 1],
];
}
/**
* @dataProvider invalidObjectArgsProvider
* @expectedException \InvalidArgumentException
*/
public function testDeleteCommentsAtObjectInvalidInput($type, $id) {
$manager = $this->getManager();
$manager->deleteCommentsAtObject($type, $id);
}
public function testDeleteCommentsAtObject() {
$ids = [];
$ids[] = $this->addDatabaseEntry(0, 0);
$ids[] = $this->addDatabaseEntry(0, 0);
$ids[] = $this->addDatabaseEntry(0, 0);
$manager = $this->getManager();
// just to make sure they are really set, with correct actor data
$comment = $manager->get(strval($ids[1]));
$this->assertSame($comment->getObjectType(), 'file');
$this->assertSame($comment->getObjectId(), 'file64');
$wasSuccessful = $manager->deleteCommentsAtObject('file', 'file64');
$this->assertTrue($wasSuccessful);
$verified = 0;
foreach($ids as $id) {
try {
$manager->get(strval($id));
} catch (\OCP\Comments\NotFoundException $e) {
$verified++;
}
}
$this->assertSame($verified, 3);
// actor info is gone from DB, but when database interaction is alright,
// we still expect to get true back
$wasSuccessful = $manager->deleteCommentsAtObject('file', 'file64');
$this->assertTrue($wasSuccessful);
}
}

View File

@ -61,6 +61,7 @@ class Server extends \Test\TestCase {
['CapabilitiesManager', '\OC\CapabilitiesManager'],
['ContactsManager', '\OC\ContactsManager'],
['ContactsManager', '\OCP\Contacts\IManager'],
['CommentsManager', '\OCP\Comments\ICommentsManager'],
['Crypto', '\OC\Security\Crypto'],
['Crypto', '\OCP\Security\ICrypto'],
['CryptoWrapper', '\OC\Session\CryptoWrapper'],
@ -173,4 +174,16 @@ class Server extends \Test\TestCase {
$this->assertInstanceOf('\OC_EventSource', $this->server->createEventSource(), 'service returned by "createEventSource" did not return the right class');
$this->assertInstanceOf('\OCP\IEventSource', $this->server->createEventSource(), 'service returned by "createEventSource" did not return the right class');
}
public function testOverwriteDefaultCommentsManager() {
$config = $this->server->getConfig();
$defaultManagerFactory = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
$config->setSystemValue('comments.managerFactory', '\Test\Comments\FakeFactory');
$manager = $this->server->getCommentsManager();
$this->assertInstanceOf('\OCP\Comments\ICommentsManager', $manager);
$config->setSystemValue('comments.managerFactory', $defaultManagerFactory);
}
}