diff --git a/src/Dao/UserDao.php b/src/Dao/UserDao.php index 6b04cff0..18bae74b 100644 --- a/src/Dao/UserDao.php +++ b/src/Dao/UserDao.php @@ -13,4 +13,9 @@ class UserDao extends AbstractDao implements ICrudDao $arrayEntity = $this->collection->findOne(['name' => $userName]); return $this->entityConverter->toEntity($arrayEntity); } + + public function hasAnyUsers() + { + return (bool) $this->collection->findOne(); + } } diff --git a/src/Entities/User.php b/src/Entities/User.php index dcbbaac9..1e8bc547 100644 --- a/src/Entities/User.php +++ b/src/Entities/User.php @@ -11,8 +11,9 @@ final class User extends Entity const ACCESS_RANK_ADMINISTRATOR = 5; public $name; - public $passwordHash; public $email; - public $registrationDate; + public $passwordHash; + public $accessRank; + public $registrationTime; public $lastLoginTime; } diff --git a/src/Services/EmailService.php b/src/Services/EmailService.php index f05bfcfe..cd5dbccd 100644 --- a/src/Services/EmailService.php +++ b/src/Services/EmailService.php @@ -3,6 +3,7 @@ namespace Szurubooru\Services; class EmailService { + //todo: refactor this to generic validation public function validateEmail($email) { if (!$email) diff --git a/src/Services/PasswordService.php b/src/Services/PasswordService.php index 34576994..e80ead7a 100644 --- a/src/Services/PasswordService.php +++ b/src/Services/PasswordService.php @@ -10,6 +10,7 @@ class PasswordService $this->config = $config; } + //todo: refactor this to generic validation public function validatePassword($password) { if (!$password) diff --git a/src/Services/UserService.php b/src/Services/UserService.php index 0433de4e..043a001e 100644 --- a/src/Services/UserService.php +++ b/src/Services/UserService.php @@ -38,13 +38,18 @@ class UserService $user->name = $formData->name; $user->email = $formData->email; $user->passwordHash = $this->passwordService->getHash($formData->password); + $user->accessRank = $this->userDao->hasAnyUsers() + ? \Szurubooru\Entities\User::ACCESS_RANK_REGULAR_USER + : \Szurubooru\Entities\User::ACCESS_RANK_ADMINISTRATOR; $user->registrationTime = $this->timeService->getCurrentTime(); + $user->lastLoginTime = null; //todo: send activation mail if necessary return $this->userDao->save($user); } + //todo: refactor this to generic validation public function validateUserName(&$userName) { $userName = trim($userName); @@ -53,10 +58,10 @@ class UserService throw new \DomainException('User name cannot be empty.'); $minUserNameLength = intval($this->config->users->minUserNameLength); - $maxUserNameLength = intval($this->config->users->maxserNameLength); + $maxUserNameLength = intval($this->config->users->maxUserNameLength); if (strlen($userName) < $minUserNameLength) throw new \DomainException('User name must have at least ' . $minUserNameLength . ' character(s).'); - if (strlen($userName) < $maxUserNameLength) - throw new \DomainException('User name must have at most ' . $minUserNameLength . ' character(s).'); + if (strlen($userName) > $maxUserNameLength) + throw new \DomainException('User name must have at most ' . $maxUserNameLength . ' character(s).'); } } diff --git a/tests/Services/UserServiceTest.php b/tests/Services/UserServiceTest.php new file mode 100644 index 00000000..cf5190ee --- /dev/null +++ b/tests/Services/UserServiceTest.php @@ -0,0 +1,100 @@ +configMock = new \Szurubooru\Config; + $this->userDaoMock = $this->mock(\Szurubooru\Dao\UserDao::class); + $this->passwordServiceMock = $this->mock(\Szurubooru\Services\PasswordService::class); + $this->emailServiceMock = $this->mock(\Szurubooru\Services\EmailService::class); + $this->timeServiceMock = $this->mock(\Szurubooru\Services\TimeService::class); + } + + public function testValidRegistration() + { + $formData = new \Szurubooru\FormData\RegistrationFormData; + $formData->name = 'user'; + $formData->password = 'password'; + $formData->email = 'email'; + + //todo: this shouldn't be needed. refactor validation + $this->configMock->users = new \StdClass; + $this->configMock->users->minUserNameLength = 0; + $this->configMock->users->maxUserNameLength = 50; + + $this->passwordServiceMock->method('getHash')->willReturn('hash'); + $this->timeServiceMock->method('getCurrentTime')->willReturn('now'); + $this->userDaoMock->method('hasAnyUsers')->willReturn(true); + $this->userDaoMock->method('save')->will($this->returnArgument(0)); + + $userService = $this->getUserService(); + $savedUser = $userService->register($formData); + + $this->assertEquals('user', $savedUser->name); + $this->assertEquals('email', $savedUser->email); + $this->assertEquals('hash', $savedUser->passwordHash); + $this->assertEquals(\Szurubooru\Entities\User::ACCESS_RANK_REGULAR_USER, $savedUser->accessRank); + $this->assertEquals('now', $savedUser->registrationTime); + } + + public function testAccessRankOfFirstUser() + { + $formData = new \Szurubooru\FormData\RegistrationFormData; + $formData->name = 'user'; + $formData->password = 'password'; + $formData->email = 'email'; + + //todo: this shouldn't be needed. refactor validation + $this->configMock->users = new \StdClass; + $this->configMock->users->minUserNameLength = 0; + $this->configMock->users->maxUserNameLength = 50; + + $this->userDaoMock->method('hasAnyUsers')->willReturn(false); + $this->userDaoMock->method('save')->will($this->returnArgument(0)); + + $userService = $this->getUserService(); + $savedUser = $userService->register($formData); + + $this->assertEquals(\Szurubooru\Entities\User::ACCESS_RANK_ADMINISTRATOR, $savedUser->accessRank); + } + + public function testRegistrationWhenUserExists() + { + $formData = new \Szurubooru\FormData\RegistrationFormData; + $formData->name = 'user'; + $formData->password = 'password'; + $formData->email = 'email'; + + //todo: this shouldn't be needed. refactor validation + $this->configMock->users = new \StdClass; + $this->configMock->users->minUserNameLength = 0; + $this->configMock->users->maxUserNameLength = 50; + + $this->userDaoMock->method('hasAnyUsers')->willReturn(true); + $this->userDaoMock->method('getByName')->willReturn(new \Szurubooru\Entities\User()); + $this->userDaoMock->method('save')->will($this->returnArgument(0)); + + $userService = $this->getUserService(); + + $this->setExpectedException(\Exception::class, 'User with this name already exists'); + $savedUser = $userService->register($formData); + } + + private function getUserService() + { + return new \Szurubooru\Services\UserService( + $this->configMock, + $this->userDaoMock, + $this->passwordServiceMock, + $this->emailServiceMock, + $this->timeServiceMock); + } +}