Unit tests for comments; fixed anonymous comments

This commit is contained in:
Marcin Kurczewski 2014-05-05 11:08:03 +02:00
parent 76d544572c
commit 8c3feaeccf
7 changed files with 533 additions and 2 deletions

View file

@ -28,7 +28,7 @@ class AddCommentJob extends AbstractJob
public function requiresAuthentication() public function requiresAuthentication()
{ {
return true; return false;
} }
public function requiresConfirmedEmail() public function requiresConfirmedEmail()

View file

@ -2,7 +2,12 @@
abstract class AbstractEntity implements IValidatable abstract class AbstractEntity implements IValidatable
{ {
public $id; public $id;
protected $__cache; protected $__cache = [];
public function resetCache()
{
$this->__cache = [];
}
public function setCache($key, $value) public function setCache($key, $value)
{ {

View file

@ -7,4 +7,35 @@ class AbstractTest
{ {
$this->assert = new Assert(); $this->assert = new Assert();
} }
protected function mockUser()
{
$user = UserModel::spawn();
$user->setAccessRank(new AccessRank(AccessRank::Registered));
$user->setName('dummy');
$user->passHash = UserModel::hashPassword('ble', $user->passSalt);
return UserModel::save($user);
}
protected function mockPost()
{
$post = PostModel::spawn();
$post->setType(new PostType(PostType::Image));
return PostModel::save($post);
}
protected function login($user)
{
Auth::setCurrentUser($user);
}
protected function mockComment($owner)
{
$post = $this->mockPost();
$comment = CommentModel::spawn();
$comment->setPost($post);
$comment->setCommenter($owner);
$comment->text = 'test test';
return CommentModel::save($comment);
}
} }

157
tests/CommentAddTest.php Normal file
View file

@ -0,0 +1,157 @@
<?php
class CommentAddTest extends AbstractTest
{
protected $user;
public function testSaving()
{
$this->prepare();
$text = 'alohaaaaaaa';
$comment = $this->assert->doesNotThrow(function() use ($text)
{
return $this->runApi($text);
});
$this->assert->areEqual(1, CommentModel::getCount());
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual(Auth::getCurrentUser()->id, $comment->getCommenter()->id);
$this->assert->areEqual(1, $comment->getPost()->id);
$this->assert->isNotNull($comment->commentDate);
$this->assert->doesNotThrow(function() use ($comment)
{
UserModel::findById($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');
}
public function testAnonymous()
{
$this->prepare();
Auth::setCurrentUser(null);
getConfig()->privileges->addComment = 'anonymous';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::AddComment)));
$text = 'alohaaaaaaa';
$comment = $this->assert->doesNotThrow(function() use ($text)
{
return $this->runApi($text);
});
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual(Auth::getCurrentUser()->id, $comment->getCommenter()->id);
$this->assert->areEqual(UserModel::getAnonymousName(), $comment->getCommenter()->getName());
}
public function testPrivilegeDependancies()
{
$this->prepare();
getConfig()->privileges->{'editComment'} = 'nobody';
getConfig()->privileges->{'editComment.own'} = 'nobody';
getConfig()->privileges->{'editComment.all'} = 'nobody';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::AddComment)));
$this->assert->isFalse(Access::check(new Privilege(Privilege::EditComment)));
$this->assert->doesNotThrow(function()
{
return $this->runApi('alohaaaaaaa');
}, 'insufficient privileges');
}
public function testWrongPostId()
{
$this->prepare();
$this->assert->throws(function()
{
return Api::run(
new AddCommentJob(),
[
AddCommentJob::POST_ID => 100,
AddCommentJob::TEXT => 'alohaa',
]);
}, 'Invalid post ID');
}
protected function runApi($text)
{
$post = $this->mockPost();
return Api::run(
new AddCommentJob(),
[
AddCommentJob::POST_ID => $post->id,
AddCommentJob::TEXT => $text,
]);
}
protected function prepare()
{
$this->login($this->mockUser());
}
}

110
tests/CommentDeleteTest.php Normal file
View file

@ -0,0 +1,110 @@
<?php
class CommentDeleteTest extends AbstractTest
{
public function testOwn()
{
$this->prepare();
$this->assert->doesNotThrow(function()
{
return $this->runApi();
});
$this->assert->areEqual(0, CommentModel::getCount());
}
public function testNoAuth()
{
$this->prepare();
Auth::setCurrentUser(null);
$this->assert->throws(function()
{
$this->assert->isFalse(Auth::isLoggedIn());
return $this->runApi();
}, 'Not logged in');
}
public function testOwnAccessDenial()
{
$this->prepare();
getConfig()->privileges->{'deleteComment.own'} = 'nobody';
Access::init();
$this->assert->isFalse(Access::check(new Privilege(Privilege::DeleteComment)));
$this->assert->throws(function()
{
return $this->runApi();
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
getConfig()->privileges->{'deleteComment.all'} = 'nobody';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::DeleteComment)));
$this->assert->doesNotThrow(function()
{
return $this->runApi();
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
getConfig()->privileges->{'deleteComment.all'} = 'nobody';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::DeleteComment)));
$this->assert->isTrue(Access::check(new Privilege(Privilege::DeleteComment, 'own')));
$this->assert->isFalse(Access::check(new Privilege(Privilege::DeleteComment, 'all')));
$this->assert->throws(function() use ($comment)
{
Api::run(
new DeleteCommentJob(),
[
DeleteCommentJob::COMMENT_ID => $comment->id,
]);
}, 'Insufficient privileges');
}
public function testWrongCommentId()
{
$this->prepare();
$this->assert->throws(function()
{
return Api::run(
new DeleteCommentJob(),
[
DeleteCommentJob::COMMENT_ID => 100,
]);
}, 'Invalid comment ID');
}
protected function runApi()
{
$comment = $this->mockComment(Auth::getCurrentUser());
return Api::run(
new DeleteCommentJob(),
[
DeleteCommentJob::COMMENT_ID => $comment->id,
]);
}
protected function prepare()
{
$this->login($this->mockUser());
}
}

157
tests/CommentEditTest.php Normal file
View file

@ -0,0 +1,157 @@
<?php
class CommentEditTest extends AbstractTest
{
public function testOwn()
{
$this->prepare();
$text = 'alohaaaaaaa';
$comment = $this->assert->doesNotThrow(function() use ($text)
{
return $this->runApi($text);
});
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual(Auth::getCurrentUser()->id, $comment->getCommenter()->id);
$this->assert->areEqual(1, $comment->getPost()->id);
$this->assert->isNotNull($comment->commentDate);
$this->assert->doesNotThrow(function() use ($comment)
{
UserModel::findById($comment->id);
});
}
public function testOwnAlmostTooShortText()
{
$this->prepare();
$this->assert->doesNotThrow(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->minLength));
});
}
public function testOwnAlmostTooLongText()
{
$this->prepare();
$this->assert->doesNotThrow(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->maxLength));
});
}
public function testOwnTooShortText()
{
$this->prepare();
$this->assert->throws(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->minLength - 1));
}, 'Comment must have at least');
}
public function testOwnTooLongText()
{
$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');
}, 'Not logged in');
}
public function testOwnAccessDenial()
{
$this->prepare();
getConfig()->privileges->{'editComment.own'} = 'nobody';
Access::init();
$this->assert->isFalse(Access::check(new Privilege(Privilege::EditComment)));
$this->assert->throws(function()
{
return $this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
getConfig()->privileges->{'editComment.all'} = 'nobody';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::EditComment)));
$this->assert->doesNotThrow(function()
{
return $this->runApi('alohaaaaaaa');
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
getConfig()->privileges->{'editComment.all'} = 'nobody';
Access::init();
$this->assert->isTrue(Access::check(new Privilege(Privilege::EditComment)));
$this->assert->isTrue(Access::check(new Privilege(Privilege::EditComment, 'own')));
$this->assert->isFalse(Access::check(new Privilege(Privilege::EditComment, 'all')));
$this->assert->throws(function() use ($comment)
{
Api::run(
new EditCommentJob(),
[
EditCommentJob::COMMENT_ID => $comment->id,
EditCommentJob::TEXT => 'alohaa',
]);
}, 'Insufficient privileges');
}
public function testWrongCommentId()
{
$this->prepare();
$this->assert->throws(function()
{
return Api::run(
new EditCommentJob(),
[
EditCommentJob::COMMENT_ID => 100,
EditCommentJob::TEXT => 'alohaa',
]);
}, 'Invalid comment ID');
}
protected function runApi($text)
{
$comment = $this->mockComment(Auth::getCurrentUser());
return Api::run(
new EditCommentJob(),
[
EditCommentJob::COMMENT_ID => $comment->id,
EditCommentJob::TEXT => $text,
]);
}
protected function prepare()
{
$this->login($this->mockUser());
}
}

71
tests/CommentListTest.php Normal file
View file

@ -0,0 +1,71 @@
<?php
class CommentListTest extends AbstractTest
{
public function testNone()
{
$this->assert->areEqual(0, CommentModel::getCount());
$ret = $this->runApi(1);
$this->assert->areEqual(0, count($ret->entities));
}
public function testSingle()
{
$this->assert->areEqual(0, CommentModel::getCount());
$this->mockComment($this->mockUser());
$ret = $this->runApi(1);
$this->assert->areEqual(1, count($ret->entities));
$post = $ret->entities[0];
$samePost = $this->assert->doesNotThrow(function() use ($post)
{
return PostModel::findById($post->id);
});
//posts retrieved via ListCommentsJob should already have cached its comments
$this->assert->areNotEquivalent($post, $samePost);
$post->resetCache();
$samePost->resetCache();
$this->assert->areEquivalent($post, $samePost);
}
public function testPaging()
{
getConfig()->comments->commentsPerPage = 2;
$this->assert->areEqual(0, CommentModel::getCount());
$this->mockComment($this->mockUser());
$this->mockComment($this->mockUser());
$this->mockComment($this->mockUser());
$ret = $this->runApi(1);
$this->assert->areEqual(2, count($ret->entities));
$ret = $this->runApi(2);
$this->assert->areEqual(1, count($ret->entities));
}
public function testAccessDenial()
{
getConfig()->privileges->listComments = 'nobody';
Access::init();
$this->assert->isFalse(Access::check(new Privilege(Privilege::ListComments)));
$this->assert->throws(function()
{
$this->runApi(1);
}, 'Insufficient privileges');
}
protected function runApi($page)
{
return Api::run(
new ListCommentsJob(),
[
ListCommentsJob::PAGE_NUMBER => $page,
]);
}
}