diff --git a/src/Api/Jobs/AddCommentJob.php b/src/Api/Jobs/AddCommentJob.php index 1475bc33..f6dc4fb7 100644 --- a/src/Api/Jobs/AddCommentJob.php +++ b/src/Api/Jobs/AddCommentJob.php @@ -5,13 +5,13 @@ class AddCommentJob extends AbstractJob { $user = Auth::getCurrentUser(); $post = PostModel::findById($this->getArgument(self::POST_ID)); - $text = CommentModel::validateText($this->getArgument(self::TEXT)); + $text = $this->getArgument(self::TEXT); $comment = CommentModel::spawn(); $comment->setCommenter($user); $comment->setPost($post); - $comment->commentDate = time(); - $comment->text = $text; + $comment->setDateTime(time()); + $comment->setText($text); CommentModel::save($comment); Logger::log('{user} commented on {post}', [ diff --git a/src/Api/Jobs/EditCommentJob.php b/src/Api/Jobs/EditCommentJob.php index 7daa110c..8315bc2d 100644 --- a/src/Api/Jobs/EditCommentJob.php +++ b/src/Api/Jobs/EditCommentJob.php @@ -12,8 +12,8 @@ class EditCommentJob extends AbstractJob { $comment = $this->comment; - $comment->commentDate = time(); - $comment->text = CommentModel::validateText($this->getArgument(self::TEXT)); + $comment->setDateTime(time()); + $comment->setText($this->getArgument(self::TEXT)); CommentModel::save($comment); Logger::log('{user} edited comment in {post}', [ diff --git a/src/Api/Jobs/PreviewCommentJob.php b/src/Api/Jobs/PreviewCommentJob.php index bb1ad195..068209fa 100644 --- a/src/Api/Jobs/PreviewCommentJob.php +++ b/src/Api/Jobs/PreviewCommentJob.php @@ -4,12 +4,17 @@ class PreviewCommentJob extends AbstractJob public function execute() { $user = Auth::getCurrentUser(); - $text = CommentModel::validateText($this->getArgument(self::TEXT)); + $text = $this->getArgument(self::TEXT); + $post = PostModel::findById($this->getArgument(self::POST_ID)); $comment = CommentModel::spawn(); $comment->setCommenter($user); - $comment->commentDate = time(); - $comment->text = $text; + $comment->setDateTime(time()); + $comment->setText($text); + $comment->setPost($post); + + $comment->validate(); + return $comment; } @@ -20,7 +25,7 @@ class PreviewCommentJob extends AbstractJob public function requiresAuthentication() { - return true; + return false; } public function requiresConfirmedEmail() diff --git a/src/Controllers/CommentController.php b/src/Controllers/CommentController.php index aa670a0e..fc9314fa 100644 --- a/src/Controllers/CommentController.php +++ b/src/Controllers/CommentController.php @@ -19,10 +19,11 @@ class CommentController $comment = Api::run( new PreviewCommentJob(), [ + PreviewCommentJob::POST_ID => InputHelper::get('post-id'), PreviewCommentJob::TEXT => InputHelper::get('text') ]); - getContext()->transport->textPreview = $comment->getText(); + getContext()->transport->textPreview = $comment->getTextMarkdown(); } public function addAction() diff --git a/src/Models/CommentModel.php b/src/Models/CommentModel.php index 37053956..41e94aa1 100644 --- a/src/Models/CommentModel.php +++ b/src/Models/CommentModel.php @@ -2,7 +2,7 @@ use \Chibi\Sql as Sql; use \Chibi\Database as Database; -class CommentModel extends AbstractCrudModel +final class CommentModel extends AbstractCrudModel { public static function getTableName() { @@ -12,7 +12,7 @@ class CommentModel extends AbstractCrudModel public static function spawn() { $comment = new CommentEntity; - $comment->commentDate = time(); + $comment->setDateTime(time()); return $comment; } @@ -25,10 +25,10 @@ class CommentModel extends AbstractCrudModel self::forgeId($comment); $bindings = [ - 'text' => $comment->text, - 'post_id' => $comment->postId, - 'comment_date' => $comment->commentDate, - 'commenter_id' => $comment->commenterId]; + 'text' => $comment->getText(), + 'post_id' => $comment->getPostId(), + 'comment_date' => $comment->getDateTime(), + 'commenter_id' => $comment->getCommenterId()]; $stmt = new Sql\UpdateStatement(); $stmt->setTable('comment'); @@ -74,7 +74,7 @@ class CommentModel extends AbstractCrudModel public static function preloadCommenters($comments) { self::preloadOneToMany($comments, - function($comment) { return $comment->commenterId; }, + function($comment) { return $comment->getCommenterId(); }, function($user) { return $user->getId(); }, function($userIds) { return UserModel::findByIds($userIds); }, function($comment, $user) { return $comment->setCache('commenter', $user); }); @@ -83,25 +83,9 @@ class CommentModel extends AbstractCrudModel public static function preloadPosts($comments) { self::preloadOneToMany($comments, - function($comment) { return $comment->postId; }, + function($comment) { return $comment->getPostId(); }, function($post) { return $post->getId(); }, function($postIds) { return PostModel::findByIds($postIds); }, function($comment, $post) { $comment->setCache('post', $post); }); } - - - - public static function validateText($text) - { - $text = trim($text); - $config = getConfig(); - - if (strlen($text) < $config->comments->minLength) - throw new SimpleException('Comment must have at least %d characters', $config->comments->minLength); - - if (strlen($text) > $config->comments->maxLength) - throw new SimpleException('Comment must have at most %d characters', $config->comments->maxLength); - - return $text; - } } diff --git a/src/Models/Entities/CommentEntity.php b/src/Models/Entities/CommentEntity.php index 6a473763..5683b77b 100644 --- a/src/Models/Entities/CommentEntity.php +++ b/src/Models/Entities/CommentEntity.php @@ -1,48 +1,93 @@ getText()); + $config = getConfig(); + + if (strlen($text) < $config->comments->minLength) + throw new SimpleException('Comment must have at least %d characters', $config->comments->minLength); + + if (strlen($text) > $config->comments->maxLength) + throw new SimpleException('Comment must have at most %d characters', $config->comments->maxLength); + + if (!$this->getPostId()) + throw new SimpleException('Trying to save comment that doesn\'t refer to any post'); + + if (!$this->getDateTime()) + throw new SimpleException('Trying to save comment that has no creation date specified'); + + $this->setText($text); } public function getText() { - return TextHelper::parseMarkdown($this->text); + return $this->text; } - public function setPost($post) + public function getTextMarkdown() { - $this->setCache('post', $post); - $this->postId = $post->id; + return TextHelper::parseMarkdown($this->getText()); } - public function setCommenter($user) + public function setText($text) { - $this->setCache('commenter', $user); - $this->commenterId = $user ? $user->id : null; + $this->text = $text; } public function getPost() { if ($this->hasCache('post')) return $this->getCache('post'); - $post = PostModel::findById($this->postId); + $post = PostModel::findById($this->getPostId()); $this->setCache('post', $post); return $post; } + public function getPostId() + { + return $this->postId; + } + + public function setPost($post) + { + $this->setCache('post', $post); + $this->postId = $post->getId(); + } + + public function getDateTime() + { + return $this->commentDate; + } + + public function setDateTime($dateTime) + { + $this->commentDate = $dateTime; + } + public function getCommenter() { if ($this->hasCache('commenter')) return $this->getCache('commenter'); - $user = UserModel::findById($this->commenterId, false); + $user = UserModel::findById($this->getCommenterId(), false); $this->setCache('commenter', $user); return $user; } + + public function getCommenterId() + { + return $this->commenterId; + } + + public function setCommenter($user) + { + $this->setCache('commenter', $user); + $this->commenterId = $user ? $user->getId() : null; + } } diff --git a/src/Views/comment-edit.phtml b/src/Views/comment-edit.phtml index ced63b85..c0be8960 100644 --- a/src/Views/comment-edit.phtml +++ b/src/Views/comment-edit.phtml @@ -16,7 +16,7 @@ Assets::addScript('comment-edit.js');
- +
diff --git a/src/Views/comment-small.phtml b/src/Views/comment-small.phtml index d1b1d463..e2f52f0f 100644 --- a/src/Views/comment-small.phtml +++ b/src/Views/comment-small.phtml @@ -32,8 +32,8 @@ Assets::addScript('comment-edit.js'); - - context->comment->commentDate, false) ?> + + context->comment->getDateTime(), false) ?>
- context->comment->getText() ?> + context->comment->getTextMarkdown() ?>
diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php index 043b1c31..822ec9b8 100644 --- a/tests/AbstractTest.php +++ b/tests/AbstractTest.php @@ -35,7 +35,7 @@ class AbstractTest $comment = CommentModel::spawn(); $comment->setPost($post); $comment->setCommenter($owner); - $comment->text = 'test test'; + $comment->setText('test test'); return CommentModel::save($comment); } } diff --git a/tests/CommentAddTest.php b/tests/CommentAddTest.php index 670c0b7a..c8a5ca6b 100644 --- a/tests/CommentAddTest.php +++ b/tests/CommentAddTest.php @@ -14,10 +14,10 @@ class CommentAddTest extends AbstractTest }); $this->assert->areEqual(1, CommentModel::getCount()); - $this->assert->areEqual($text, $comment->text); + $this->assert->areEqual($text, $comment->getText()); $this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId()); $this->assert->areEqual(1, $comment->getPost()->getId()); - $this->assert->isNotNull($comment->commentDate); + $this->assert->isNotNull($comment->getDateTime()); $this->assert->doesNotThrow(function() use ($comment) { CommentModel::findById($comment->getId()); @@ -101,7 +101,7 @@ class CommentAddTest extends AbstractTest return $this->runApi($text); }); - $this->assert->areEqual($text, $comment->text); + $this->assert->areEqual($text, $comment->getText()); $this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId()); $this->assert->areEqual(UserModel::getAnonymousName(), $comment->getCommenter()->getName()); } diff --git a/tests/CommentEditTest.php b/tests/CommentEditTest.php index 73a71f32..49e48022 100644 --- a/tests/CommentEditTest.php +++ b/tests/CommentEditTest.php @@ -11,10 +11,10 @@ class CommentEditTest extends AbstractTest return $this->runApi($text); }); - $this->assert->areEqual($text, $comment->text); + $this->assert->areEqual($text, $comment->getText()); $this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId()); $this->assert->areEqual(1, $comment->getPost()->getId()); - $this->assert->isNotNull($comment->commentDate); + $this->assert->isNotNull($comment->getDateTime()); $this->assert->doesNotThrow(function() use ($comment) { CommentModel::findById($comment->getId()); diff --git a/tests/CommentPreviewTest.php b/tests/CommentPreviewTest.php new file mode 100644 index 00000000..c72d2226 --- /dev/null +++ b/tests/CommentPreviewTest.php @@ -0,0 +1,103 @@ +prepare(); + + $text = 'alohaaaaaaa'; + $comment = $this->assert->doesNotThrow(function() use ($text) + { + return $this->runApi($text); + }); + + $this->assert->areEqual(0, CommentModel::getCount()); + $this->assert->areEqual($text, $comment->getText()); + $this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId()); + $this->assert->isNotNull($comment->getDateTime()); + $this->assert->throws(function() use ($comment) + { + CommentModel::findById($comment->getId()); + }, 'Invalid comment ID'); + } + + public function testAlmostTooShortText() + { + $this->prepare(); + $this->assert->doesNotThrow(function() + { + return $this->runApi(str_repeat('b', getConfig()->comments->minLength)); + }); + } + + public function testAlmostTooLongText() + { + $this->prepare(); + $this->assert->doesNotThrow(function() + { + return $this->runApi(str_repeat('b', getConfig()->comments->maxLength)); + }); + } + + public function testTooShortText() + { + $this->prepare(); + $this->assert->throws(function() + { + return $this->runApi(str_repeat('b', getConfig()->comments->minLength - 1)); + }, 'Comment must have at least'); + } + + public function testTooLongText() + { + $this->prepare(); + $this->assert->throws(function() + { + return $this->runApi(str_repeat('b', getConfig()->comments->maxLength + 1)); + }, 'Comment must have at most'); + } + + public function testNoAuth() + { + $this->prepare(); + Auth::setCurrentUser(null); + + $this->assert->throws(function() + { + $this->assert->isFalse(Auth::isLoggedIn()); + return $this->runApi('alohaaaaaaa'); + }, 'Insufficient privileges'); + } + + public function testAccessDenial() + { + $this->prepare(); + + getConfig()->privileges->addComment = 'nobody'; + Access::init(); + $this->assert->isFalse(Access::check(new Privilege(Privilege::AddComment))); + + $this->assert->throws(function() + { + return $this->runApi('alohaaaaaaa'); + }, 'Insufficient privileges'); + } + + + protected function runApi($text) + { + $post = $this->mockPost(); + + return Api::run( + new PreviewCommentJob(), + [ + PreviewCommentJob::POST_ID => $post->getId(), + PreviewCommentJob::TEXT => $text, + ]); + } + + protected function prepare() + { + $this->login($this->mockUser()); + } +}