Fixed entity retrievers

This commit is contained in:
Marcin Kurczewski 2014-05-12 18:59:17 +02:00
parent 3596a8cdc7
commit 96ebd2c89f
14 changed files with 435 additions and 15 deletions

View file

@ -8,6 +8,11 @@ class CommentRetriever implements IEntityRetriever
$this->job = $job;
}
public function getJob()
{
return $this->job;
}
public function tryRetrieve()
{
if ($this->job->hasArgument(JobArgs::ARG_COMMENT_ENTITY))

View file

@ -2,6 +2,7 @@
interface IEntityRetriever
{
public function __construct(IJob $job);
public function getJob();
public function tryRetrieve();
public function retrieve();
public function getRequiredArguments();

View file

@ -8,6 +8,11 @@ class PostRetriever implements IEntityRetriever
$this->job = $job;
}
public function getJob()
{
return $this->job;
}
public function tryRetrieve()
{
if ($this->job->hasArgument(JobArgs::ARG_POST_ENTITY))
@ -17,7 +22,7 @@ class PostRetriever implements IEntityRetriever
return PostModel::getById($this->job->getArgument(JobArgs::ARG_POST_ID));
if ($this->job->hasArgument(JobArgs::ARG_POST_NAME))
return PostModel::getByName($job->getArgument(JobArgs::ARG_POST_NAME));
return PostModel::getByName($this->job->getArgument(JobArgs::ARG_POST_NAME));
return null;
}

View file

@ -8,6 +8,11 @@ class SafePostRetriever implements IEntityRetriever
$this->job = $job;
}
public function getJob()
{
return $this->job;
}
public function tryRetrieve()
{
if ($this->job->hasArgument(JobArgs::ARG_POST_ENTITY))

View file

@ -8,13 +8,21 @@ class UserRetriever implements IEntityRetriever
$this->job = $job;
}
public function getJob()
{
return $this->job;
}
public function tryRetrieve()
{
if ($this->job->hasArgument(JobArgs::ARG_USER_ENTITY))
return $this->job->getArgument(JobArgs::ARG_USER_ENTITY);
if ($this->job->hasArgument(JobArgs::ARG_USER_EMAIL))
return UserModel::getByEmail($this->job->getArgument(JobArgs::ARG_USER_EMAIL));
if ($this->job->hasArgument(JobArgs::ARG_USER_NAME))
return UserModel::getByNameOrEmail($this->job->getArgument(JobArgs::ARG_USER_NAME));
return UserModel::getByName($this->job->getArgument(JobArgs::ARG_USER_NAME));
return null;
}

View file

@ -13,9 +13,9 @@ class Auth
$config = getConfig();
$context = getContext();
$user = UserModel::tryGetByNameOrEmail($name);
$user = UserModel::tryGetByEmail($name);
if ($user === null)
throw new SimpleException('Invalid username');
$user = UserModel::getByName($name);
$passwordHash = UserModel::hashPassword($password, $user->getPasswordSalt());
if ($passwordHash != $user->getPasswordHash())

View file

@ -13,7 +13,7 @@ class StaticPagesController
{
$context->featuredPost = $featuredPost;
$context->featuredPostUnixTime = PropertyModel::get(PropertyModel::FeaturedPostUnixTime);
$context->featuredPostUser = UserModel::tryGetByNameOrEmail(
$context->featuredPostUser = UserModel::tryGetByName(
PropertyModel::get(PropertyModel::FeaturedPostUserName));
}
}

View file

@ -73,7 +73,7 @@ class PostSearchParser extends AbstractSearchParser
elseif (in_array($key, ['fav', 'favs', 'favd']))
{
$user = UserModel::getByNameOrEmail($value);
$user = UserModel::getByName($value);
$innerStmt = (new Sql\SelectStatement)
->setTable('favoritee')
->setCriterion((new Sql\ConjunctionFunctor)
@ -84,7 +84,7 @@ class PostSearchParser extends AbstractSearchParser
elseif (in_array($key, ['comment', 'comments', 'commenter', 'commented']))
{
$user = UserModel::getByNameOrEmail($value);
$user = UserModel::getByName($value);
$innerStmt = (new Sql\SelectStatement)
->setTable('comment')
->setCriterion((new Sql\ConjunctionFunctor)
@ -95,7 +95,7 @@ class PostSearchParser extends AbstractSearchParser
elseif (in_array($key, ['submit', 'upload', 'uploads', 'uploader', 'uploaded']))
{
$user = UserModel::getByNameOrEmail($value);
$user = UserModel::getByName($value);
return new Sql\EqualsFunctor('post.uploader_id', new Sql\Binding($user->getId()));
}

View file

@ -104,15 +104,15 @@ final class UserModel extends AbstractCrudModel
: null;
}
public static function getByNameOrEmail($key)
public static function getByEmail($key)
{
$ret = self::tryGetByNameOrEmail($key);
$ret = self::tryGetByEmail($key);
if (!$ret)
throw new SimpleNotFoundException('Invalid user name "%s"', $key);
throw new SimpleNotFoundException('Invalid user e-mail "%s"', $key);
return $ret;
}
public static function tryGetByNameOrEmail($key)
public static function tryGetByEmail($key)
{
$key = trim($key);
@ -120,7 +120,6 @@ final class UserModel extends AbstractCrudModel
$stmt->setColumn('*');
$stmt->setTable('user');
$stmt->setCriterion((new Sql\DisjunctionFunctor)
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding($key))))
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_unconfirmed', new Sql\Binding($key))))
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_confirmed', new Sql\Binding($key)))));

View file

@ -0,0 +1,87 @@
<?php
class CommentRetrieverTest extends AbstractTest
{
public function testRetrievingById()
{
$comment = $this->prepareComment();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_COMMENT_ID, $comment->getId());
$this->assertCorrectRetrieval($retriever, $comment);
}
public function testRetrievingByEntity()
{
$comment = $this->prepareComment();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_COMMENT_ENTITY, $comment);
$this->assertCorrectRetrieval($retriever, $comment);
}
public function testRetrievingByNonExistingId()
{
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_COMMENT_ID, 100);
$this->assert->throws(function() use ($retriever)
{
$retriever->tryRetrieve();
}, 'Invalid comment id');
}
public function testRetrievingNoArguments()
{
$retriever = $this->prepareRetriever();
$this->assertIncorrectRetrieval($retriever);
}
public function testArgumentRequirements()
{
$retriever = $this->prepareRetriever();
$this->assert->areEquivalent(
JobArgs::Alternative(
JobArgs::ARG_COMMENT_ID,
JobArgs::ARG_COMMENT_ENTITY),
$retriever->getRequiredArguments());
}
private function assertIncorrectRetrieval($retriever)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNull($retriever->tryRetrieve());
$this->assert->throws(function() use ($retriever)
{
$retriever->retrieve();
}, 'unsatisfied');
}
private function assertCorrectRetrieval($retriever, $comment)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNotNull($retriever->tryRetrieve());
$this->assert->areEqual($comment->getId(), $retriever->tryRetrieve()->getId());
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->retrieve();
});
$this->assert->areEqual($comment->getId(), $retriever->retrieve()->getId());
}
private function prepareComment()
{
return $this->mockComment($this->mockUser());
}
private function prepareRetriever()
{
$job = new EditCommentJob();
$commentRetriever = new CommentRetriever($job);
return $commentRetriever;
}
}

View file

@ -0,0 +1,96 @@
<?php
class PostRetrieverTest extends AbstractTest
{
public function testRetrievingById()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_ID, $post->getId());
$this->assertCorrectRetrieval($retriever, $post);
}
public function testRetrievingByName()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_NAME, $post->getName());
$this->assertCorrectRetrieval($retriever, $post);
}
public function testRetrievingByEntity()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_ENTITY, $post);
$this->assertCorrectRetrieval($retriever, $post);
}
public function testRetrievingByNonExistingId()
{
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_ID, 100);
$this->assert->throws(function() use ($retriever)
{
$retriever->tryRetrieve();
}, 'Invalid post ID');
}
public function testRetrievingNoArguments()
{
$retriever = $this->prepareRetriever();
$this->assertIncorrectRetrieval($retriever);
}
private function assertIncorrectRetrieval($retriever)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNull($retriever->tryRetrieve());
$this->assert->throws(function() use ($retriever)
{
$retriever->retrieve();
}, 'unsatisfied');
}
public function testArgumentRequirements()
{
$retriever = $this->prepareRetriever();
$this->assert->areEquivalent(
JobArgs::Alternative(
JobArgs::ARG_POST_NAME,
JobArgs::ARG_POST_ID,
JobArgs::ARG_POST_ENTITY),
$retriever->getRequiredArguments());
}
private function assertCorrectRetrieval($retriever, $post)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNotNull($retriever->tryRetrieve());
$this->assert->areEqual($post->getId(), $retriever->tryRetrieve()->getId());
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->retrieve();
});
$this->assert->areEqual($post->getId(), $retriever->retrieve()->getId());
}
private function preparePost()
{
return $this->mockPost($this->mockUser());
}
private function prepareRetriever()
{
$job = new EditPostJob();
$postRetriever = new PostRetriever($job);
return $postRetriever;
}
}

View file

@ -0,0 +1,95 @@
<?php
class SafePostRetrieverTest extends AbstractTest
{
public function testRetrievingById()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_ID, $post->getId());
$this->assertIncorrectRetrieval($retriever);
}
public function testRetrievingByName()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_NAME, $post->getName());
$this->assertCorrectRetrieval($retriever, $post);
}
public function testRetrievingByEntity()
{
$post = $this->preparePost();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_ENTITY, $post);
$this->assertCorrectRetrieval($retriever, $post);
}
public function testRetrievingByNonExistingName()
{
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_POST_NAME, 'nonsense');
$this->assert->throws(function() use ($retriever)
{
$retriever->tryRetrieve();
}, 'Invalid post name');
}
public function testRetrievingNoArguments()
{
$retriever = $this->prepareRetriever();
$this->assertIncorrectRetrieval($retriever);
}
public function testArgumentRequirements()
{
$retriever = $this->prepareRetriever();
$this->assert->areEquivalent(
JobArgs::Alternative(
JobArgs::ARG_POST_NAME,
JobArgs::ARG_POST_ENTITY),
$retriever->getRequiredArguments());
}
private function assertIncorrectRetrieval($retriever)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNull($retriever->tryRetrieve());
$this->assert->throws(function() use ($retriever)
{
$retriever->retrieve();
}, 'unsatisfied');
}
private function assertCorrectRetrieval($retriever, $post)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNotNull($retriever->tryRetrieve());
$this->assert->areEqual($post->getId(), $retriever->tryRetrieve()->getId());
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->retrieve();
});
$this->assert->areEqual($post->getId(), $retriever->retrieve()->getId());
}
private function preparePost()
{
return $this->mockPost($this->mockUser());
}
private function prepareRetriever()
{
$job = new EditPostJob();
$postRetriever = new SafePostRetriever($job);
return $postRetriever;
}
}

View file

@ -0,0 +1,100 @@
<?php
class UserRetrieverTest extends AbstractTest
{
public function testRetrievingByName()
{
$user = $this->prepareUser();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_USER_NAME, $user->getName());
$this->assertCorrectRetrieval($retriever, $user);
}
public function testRetrievingByEmail()
{
$user = $this->prepareUser();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_USER_EMAIL, $user->getConfirmedEmail());
$this->assertCorrectRetrieval($retriever, $user);
}
public function testRetrievingByEntity()
{
$user = $this->prepareUser();
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_USER_ENTITY, $user);
$this->assertCorrectRetrieval($retriever, $user);
}
public function testRetrievingByNonExistingName()
{
$retriever = $this->prepareRetriever();
$retriever->getJob()->setArgument(JobArgs::ARG_USER_NAME, 100);
$this->assert->throws(function() use ($retriever)
{
$retriever->tryRetrieve();
}, 'Invalid user name');
}
public function testRetrievingNoArguments()
{
$retriever = $this->prepareRetriever();
$this->assertIncorrectRetrieval($retriever);
}
public function testArgumentRequirements()
{
$retriever = $this->prepareRetriever();
$this->assert->areEquivalent(
JobArgs::Alternative(
JobArgs::ARG_USER_NAME,
JobArgs::ARG_USER_EMAIL,
JobArgs::ARG_USER_ENTITY),
$retriever->getRequiredArguments());
}
private function assertIncorrectRetrieval($retriever)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNull($retriever->tryRetrieve());
$this->assert->throws(function() use ($retriever)
{
$retriever->retrieve();
}, 'unsatisfied');
}
private function assertCorrectRetrieval($retriever, $user)
{
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->tryRetrieve();
});
$this->assert->isNotNull($retriever->tryRetrieve());
$this->assert->areEqual($user->getId(), $retriever->tryRetrieve()->getId());
$this->assert->doesNotThrow(function() use ($retriever)
{
$retriever->retrieve();
});
$this->assert->areEqual($user->getId(), $retriever->retrieve()->getId());
}
private function prepareUser()
{
$user = $this->mockUser();
$user->setConfirmedEmail('godzilla@whitestar.gov');
UserModel::save($user);
return $user;
}
private function prepareRetriever()
{
$job = new EditUserJob();
$userRetriever = new UserRetriever($job);
return $userRetriever;
}
}

View file

@ -13,6 +13,25 @@ class AuthTest extends AbstractTest
{
Auth::login('existing', 'bleee', false);
});
$this->assert->isTrue(Auth::isLoggedIn());
}
public function testLoginViaEmail()
{
getConfig()->registration->staffActivation = false;
getConfig()->registration->needEmailForRegistering = false;
$user = $this->prepareValidUser();
$user->setConfirmedEmail('godzilla@whitestar.gov');
UserModel::save($user);
$this->assert->doesNotThrow(function() use ($user)
{
Auth::login($user->getConfirmedEmail(), 'bleee', false);
});
$this->assert->isTrue(Auth::isLoggedIn());
}
public function testLogout()
@ -24,12 +43,12 @@ class AuthTest extends AbstractTest
$this->assert->isFalse(Auth::isLoggedIn());
}
public function testInvalidUser()
public function testInvalidUserName()
{
$this->assert->throws(function()
{
Auth::login('non-existing', 'wrong-password', false);
}, 'invalid username');
}, 'invalid user name');
}
public function testInvalidPassword()