From f764ebbb1e5f9105e8ee23820d4261edefe89abd Mon Sep 17 00:00:00 2001 From: nuxsmin Date: Mon, 9 Jul 2018 01:01:09 +0200 Subject: [PATCH] * [ADD] Unit testing. Work in progress * [MOD] Code refactoring --- .../AuthToken/AuthTokenRepository.php | 7 +- lib/SP/Services/Account/AccountService.php | 82 ++--- .../Services/AuthToken/AuthTokenService.php | 38 ++- lib/SP/Services/Install/Installer.php | 2 +- lib/SP/Services/ServiceItemTrait.php | 39 ++- .../Repositories/AuthTokenRepositoryTest.php | 34 +- tests/Services/Api/ApiRequestTest.php | 2 +- .../AuthToken/AuthTokenServiceTest.php | 297 ++++++++++++++++++ 8 files changed, 402 insertions(+), 99 deletions(-) create mode 100644 tests/Services/AuthToken/AuthTokenServiceTest.php diff --git a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php index 48e9d1d7..f5f5624e 100644 --- a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php +++ b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php @@ -66,7 +66,7 @@ class AuthTokenRepository extends Repository implements RepositoryItemInterface * * @param int $id * - * @return AuthTokenData + * @return QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ @@ -78,6 +78,7 @@ class AuthTokenRepository extends Repository implements RepositoryItemInterface actionId, createdBy, startDate, + vault, token, `hash` FROM AuthToken @@ -88,7 +89,7 @@ class AuthTokenRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->addParam($id); - return $this->db->doSelect($queryData)->getData(); + return $this->db->doSelect($queryData); } /** @@ -431,7 +432,7 @@ class AuthTokenRepository extends Repository implements RepositoryItemInterface public function getTokenByToken($actionId, $token) { $query = /** @lang SQL */ - 'SELECT id, actionId, userId, vault, `hash` + 'SELECT id, actionId, userId, vault, `hash`, token FROM AuthToken WHERE actionId = ? AND token = ? LIMIT 1'; diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php index 2aea99c8..8f5b297f 100644 --- a/lib/SP/Services/Account/AccountService.php +++ b/lib/SP/Services/Account/AccountService.php @@ -48,7 +48,6 @@ use SP\Services\Config\ConfigService; use SP\Services\Service; use SP\Services\ServiceException; use SP\Services\ServiceItemTrait; -use SP\Storage\Database\Database; use SP\Storage\Database\QueryResult; /** @@ -284,36 +283,23 @@ class AccountService extends Service implements AccountServiceInterface * * @param AccountRequest $accountRequest * - * @throws ServiceException * @throws \Exception */ public function update(AccountRequest $accountRequest) { - $database = $this->dic->get(Database::class); + $this->transactionAware(function () use ($accountRequest) { + $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()); - if ($database->beginTransaction()) { - try { - $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()); + // Cambiar el grupo principal si el usuario es Admin + $accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0 + && ($this->context->getUserData()->getIsAdminApp() || $this->context->getUserData()->getIsAdminAcc())); - // Cambiar el grupo principal si el usuario es Admin - $accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0 - && ($this->context->getUserData()->getIsAdminApp() || $this->context->getUserData()->getIsAdminAcc())); + $this->addHistory($accountRequest->id); - $this->addHistory($accountRequest->id); + $this->accountRepository->update($accountRequest); - $this->accountRepository->update($accountRequest); - - $this->updateItems($accountRequest); - - $database->endTransaction(); - } catch (\Exception $e) { - $database->rollbackTransaction(); - - throw $e; - } - } else { - throw new ServiceException(__u('No es posible iniciar una transacción')); - } + $this->updateItems($accountRequest); + }, $this->dic); } /** @@ -393,33 +379,20 @@ class AccountService extends Service implements AccountServiceInterface /** * @param AccountRequest $accountRequest * - * @throws ServiceException * @throws \Exception */ public function editPassword(AccountRequest $accountRequest) { - $database = $this->dic->get(Database::class); + $this->transactionAware(function () use ($accountRequest) { + $this->addHistory($accountRequest->id); - if ($database->beginTransaction()) { - try { - $this->addHistory($accountRequest->id); + $pass = $this->getPasswordEncrypted($accountRequest->pass); - $pass = $this->getPasswordEncrypted($accountRequest->pass); + $accountRequest->pass = $pass['pass']; + $accountRequest->key = $pass['key']; - $accountRequest->pass = $pass['pass']; - $accountRequest->key = $pass['key']; - - $this->accountRepository->editPassword($accountRequest); - - $database->endTransaction(); - } catch (\Exception $e) { - $database->rollbackTransaction(); - - throw $e; - } - } else { - throw new ServiceException(__u('No es posible iniciar una transacción')); - } + $this->accountRepository->editPassword($accountRequest); + }, $this->dic); } /** @@ -440,30 +413,17 @@ class AccountService extends Service implements AccountServiceInterface * @param $historyId * @param $accountId * - * @throws ServiceException * @throws \Exception */ public function editRestore($historyId, $accountId) { - $database = $this->dic->get(Database::class); + $this->transactionAware(function () use ($historyId, $accountId) { + $this->addHistory($accountId); - if ($database->beginTransaction()) { - try { - $this->addHistory($accountId); - - if (!$this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId())) { - throw new ServiceException(__u('Error al restaurar cuenta')); - } - - $database->endTransaction(); - } catch (\Exception $e) { - $database->rollbackTransaction(); - - throw $e; + if (!$this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId())) { + throw new ServiceException(__u('Error al restaurar cuenta')); } - } else { - throw new ServiceException(__u('No es posible iniciar una transacción')); - } + }, $this->dic); } /** diff --git a/lib/SP/Services/AuthToken/AuthTokenService.php b/lib/SP/Services/AuthToken/AuthTokenService.php index 1148ac72..9dd17da1 100644 --- a/lib/SP/Services/AuthToken/AuthTokenService.php +++ b/lib/SP/Services/AuthToken/AuthTokenService.php @@ -33,6 +33,7 @@ use SP\Core\Exceptions\SPException; use SP\DataModel\AuthTokenData; use SP\DataModel\ItemSearchData; use SP\Repositories\AuthToken\AuthTokenRepository; +use SP\Repositories\NoSuchItemException; use SP\Services\Service; use SP\Services\ServiceException; use SP\Services\ServiceItemTrait; @@ -103,27 +104,27 @@ class AuthTokenService extends Service /** * @param $id * - * @return mixed + * @return AuthTokenData * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ public function getById($id) { - return $this->authTokenRepository->getById($id); + return $this->authTokenRepository->getById($id)->getData(); } /** * @param $id * * @return AuthTokenService - * @throws SPException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws NoSuchItemException */ public function delete($id) { if ($this->authTokenRepository->delete($id) === 0) { - throw new SPException(__u('Token no encontrado'), SPException::INFO); + throw new NoSuchItemException(__u('Token no encontrado')); } return $this; @@ -220,6 +221,11 @@ class AuthTokenService extends Service */ private function getSecureData($token, $key) { + if (($mKey = $this->context->getTrasientKey('_masterpass')) !== null) { + return (new Vault()) + ->saveData($mKey, $key . $token); + } + return (new Vault()) ->saveData(CryptSession::getSessionKey($this->context), $key . $token); } @@ -227,29 +233,25 @@ class AuthTokenService extends Service /** * @param AuthTokenData $itemData * - * @return mixed - * @throws SPException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException + * @throws \Exception */ public function refreshAndUpdate(AuthTokenData $itemData) { - $token = $this->generateToken(); - $vault = serialize($this->getSecureData($token, $itemData->getHash())); + $this->transactionAware(function () use ($itemData) { + $token = $this->generateToken(); + $vault = serialize($this->getSecureData($token, $itemData->getHash())); - $this->authTokenRepository->refreshTokenByUserId($itemData->getUserId(), $token); - $this->authTokenRepository->refreshVaultByUserId($itemData->getUserId(), $vault, Hash::hashKey($itemData->getHash())); + $this->authTokenRepository->refreshTokenByUserId($itemData->getUserId(), $token); + $this->authTokenRepository->refreshVaultByUserId($itemData->getUserId(), $vault, Hash::hashKey($itemData->getHash())); - return $this->update($itemData, $token); + $this->update($itemData, $token); + }, $this->dic); } /** * @param AuthTokenData $itemData * @param string $token * - * @return mixed * @throws SPException * @throws \Defuse\Crypto\Exception\CryptoException * @throws \SP\Core\Exceptions\ConstraintException @@ -257,7 +259,9 @@ class AuthTokenService extends Service */ public function update(AuthTokenData $itemData, $token = null) { - return $this->authTokenRepository->update($this->injectSecureData($itemData, $token)); + if ($this->authTokenRepository->update($this->injectSecureData($itemData, $token)) === 0) { + throw new NoSuchItemException(__u('Token no encontrado')); + } } /** diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php index b528170d..8d9b581e 100644 --- a/lib/SP/Services/Install/Installer.php +++ b/lib/SP/Services/Install/Installer.php @@ -56,7 +56,7 @@ class Installer extends Service */ const VERSION = [3, 0, 0]; const VERSION_TEXT = '3.0-beta'; - const BUILD = 18070201; + const BUILD = 18070901; /** * @var ConfigService diff --git a/lib/SP/Services/ServiceItemTrait.php b/lib/SP/Services/ServiceItemTrait.php index 80fc963f..af7940fe 100644 --- a/lib/SP/Services/ServiceItemTrait.php +++ b/lib/SP/Services/ServiceItemTrait.php @@ -2,8 +2,8 @@ /** * sysPass * - * @author nuxsmin - * @link https://syspass.org + * @author nuxsmin + * @link https://syspass.org * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. @@ -24,8 +24,10 @@ namespace SP\Services; +use DI\Container; use SP\Bootstrap; use SP\DataModel\DataModelInterface; +use SP\Storage\Database\Database; /** * Trait ServiceItemTrait @@ -52,4 +54,37 @@ trait ServiceItemTrait * @return mixed */ abstract public function getAllBasic(); + + /** + * Bubbles a Closure in a database transaction + * + * @param \Closure $closure + * @param Container $container + * + * @return mixed + * @throws ServiceException + * @throws \Exception + */ + private function transactionAware(\Closure $closure, Container $container) + { + $database = $container->get(Database::class); + + if ($database->beginTransaction()) { + try { + $result = $closure->call($this); + + $database->endTransaction(); + + return $result; + } catch (\Exception $e) { + $database->rollbackTransaction(); + + debugLog('Rollback'); + + throw $e; + } + } else { + throw new ServiceException(__u('No es posible iniciar una transacción')); + } + } } \ No newline at end of file diff --git a/tests/Repositories/AuthTokenRepositoryTest.php b/tests/Repositories/AuthTokenRepositoryTest.php index 4a531425..bd7d7782 100644 --- a/tests/Repositories/AuthTokenRepositoryTest.php +++ b/tests/Repositories/AuthTokenRepositoryTest.php @@ -77,21 +77,27 @@ class AuthTokenRepositoryTest extends DatabaseTestCase */ public function testGetById() { - $authToken = self::$repository->getById(1); + $result = self::$repository->getById(1); + $this->assertEquals(1, $result->getNumRows()); - $this->assertInstanceOf(AuthTokenData::class, $authToken); - $this->assertEquals(1, $authToken->getId()); - $this->assertEquals(ActionsInterface::ACCOUNT_SEARCH, $authToken->getActionId()); - $this->assertEquals(self::AUTH_TOKEN, $authToken->getToken()); - $this->assertNull($authToken->getHash()); + $data = $result->getData(); - $authToken = self::$repository->getById(2); + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(1, $data->getId()); + $this->assertEquals(ActionsInterface::ACCOUNT_SEARCH, $data->getActionId()); + $this->assertEquals(self::AUTH_TOKEN, $data->getToken()); + $this->assertNull($data->getHash()); - $this->assertInstanceOf(AuthTokenData::class, $authToken); - $this->assertEquals(2, $authToken->getId()); - $this->assertEquals(ActionsInterface::ACCOUNT_VIEW_PASS, $authToken->getActionId()); - $this->assertEquals(self::AUTH_TOKEN, $authToken->getToken()); - $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $authToken->getHash())); + $result = self::$repository->getById(2); + $this->assertEquals(1, $result->getNumRows()); + + $data = $result->getData(); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(2, $data->getId()); + $this->assertEquals(ActionsInterface::ACCOUNT_VIEW_PASS, $data->getActionId()); + $this->assertEquals(self::AUTH_TOKEN, $data->getToken()); + $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $data->getHash())); } /** @@ -211,7 +217,7 @@ class AuthTokenRepositoryTest extends DatabaseTestCase $data = $result->getData(); $this->assertEquals(1, $result->getNumRows()); - $this->assertInstanceOf(AuthTokenData::class, $result); + $this->assertInstanceOf(AuthTokenData::class, $data); $this->assertEquals(ActionsInterface::ACCOUNT_CREATE, $data->getActionId()); $this->assertEquals($hash, $data->getHash()); $this->assertEquals(2, $data->getUserId()); @@ -324,7 +330,7 @@ class AuthTokenRepositoryTest extends DatabaseTestCase $data = $result->getData(); $this->assertEquals(1, $result->getNumRows()); - $this->assertInstanceOf(AuthTokenData::class, $result); + $this->assertInstanceOf(AuthTokenData::class, $data); $this->assertEquals(ActionsInterface::ACCOUNT_CREATE, $data->getActionId()); $this->assertEquals($hash, $data->getHash()); $this->assertEquals(3, $data->getId()); diff --git a/tests/Services/Api/ApiRequestTest.php b/tests/Services/Api/ApiRequestTest.php index 266dcfa7..2184c226 100644 --- a/tests/Services/Api/ApiRequestTest.php +++ b/tests/Services/Api/ApiRequestTest.php @@ -44,7 +44,7 @@ class ApiRequestTest extends TestCase $apiRequest = new ApiRequest(getResource('json', 'account_search.json')); $this->assertEquals(10, $apiRequest->getId()); $this->assertEquals('account/search', $apiRequest->getMethod()); - $this->assertEquals('ce4e5f2e5700d9032b0cbb0769a6d7cf8557484da492d3c32626a74bb28fb44b', $apiRequest->get('authToken')); + $this->assertEquals('2cee8b224f48e01ef48ac172e879cc7825800a9d7ce3b23783212f4758f1c146', $apiRequest->get('authToken')); $this->assertEquals('API', $apiRequest->get('text')); $this->assertEquals(5, $apiRequest->get('count')); $this->assertEquals(1, $apiRequest->get('clientId')); diff --git a/tests/Services/AuthToken/AuthTokenServiceTest.php b/tests/Services/AuthToken/AuthTokenServiceTest.php new file mode 100644 index 00000000..ef086031 --- /dev/null +++ b/tests/Services/AuthToken/AuthTokenServiceTest.php @@ -0,0 +1,297 @@ +. + */ + +namespace SP\Tests\Services\AuthToken; + +use Defuse\Crypto\Exception\CryptoException; +use SP\Core\Acl\ActionsInterface; +use SP\Core\Crypt\Hash; +use SP\Core\Crypt\Vault; +use SP\DataModel\AuthTokenData; +use SP\DataModel\ItemSearchData; +use SP\Repositories\DuplicatedItemException; +use SP\Repositories\NoSuchItemException; +use SP\Services\AuthToken\AuthTokenService; +use SP\Services\ServiceException; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Tests\DatabaseTestCase; +use SP\Util\Util; +use function SP\Tests\setupContext; + +/** + * Class AuthTokenServiceTest + * + * @package SP\Tests\Services\AuthToken + */ +class AuthTokenServiceTest extends DatabaseTestCase +{ + const AUTH_TOKEN = '2cee8b224f48e01ef48ac172e879cc7825800a9d7ce3b23783212f4758f1c146'; + const AUTH_TOKEN_PASS = 123456; + + /** + * @var AuthTokenService + */ + private static $service; + + /** + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \DI\DependencyException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + self::$dataset = 'syspass_authToken.xml'; + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el servicio + self::$service = $dic->get(AuthTokenService::class); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testDelete() + { + self::$service->delete(1); + + $this->expectException(NoSuchItemException::class); + + self::$service->delete(10); + + $this->assertEquals(4, $this->conn->getRowCount('AuthToken')); + } + + /** + * @throws ServiceException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testDeleteByIdBatch() + { + $this->assertEquals(2, self::$service->deleteByIdBatch([1, 2])); + + $this->assertEquals(0, self::$service->deleteByIdBatch([])); + + $this->expectException(ServiceException::class); + + self::$service->deleteByIdBatch([3, 10]); + + $this->assertEquals(2, $this->conn->getRowCount('AuthToken')); + + } + + /** + * @throws \Exception + */ + public function testRefreshAndUpdate() + { + $data = new AuthTokenData(); + $data->setId(1); + $data->setActionId(ActionsInterface::ACCOUNT_CREATE); + $data->setCreatedBy(1); + $data->setHash(self::AUTH_TOKEN_PASS); + $data->setUserId(2); + + self::$service->refreshAndUpdate($data); + + $resultData = self::$service->getById(1); + + $vault = Util::unserialize(Vault::class, $resultData->getVault()); + + $this->assertEquals('12345678900', $vault->getData(self::AUTH_TOKEN_PASS . $resultData->getToken())); + + $this->expectException(NoSuchItemException::class); + + $data->setId(10); + $data->setActionId(ActionsInterface::ACCOUNT_DELETE); + + $this->assertEquals(0, self::$service->refreshAndUpdate($data)); + } + + /** + * @throws ServiceException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetTokenByToken() + { + $data = self::$service->getTokenByToken(ActionsInterface::ACCOUNT_VIEW_PASS, self::AUTH_TOKEN); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(2, $data->getId()); + $this->assertEquals(ActionsInterface::ACCOUNT_VIEW_PASS, $data->getActionId()); + $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $data->getHash())); + $this->assertNotEmpty($data->getVault()); + + /** @var Vault $vault */ + $vault = Util::unserialize(Vault::class, $data->getVault()); + $this->assertEquals('12345678900', $vault->getData(self::AUTH_TOKEN_PASS . self::AUTH_TOKEN)); + + $this->expectException(CryptoException::class); + + $vault->getData(1234); + } + + /** + * @throws CryptoException + * @throws ServiceException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testUpdate() + { + $data = new AuthTokenData(); + $data->setId(1); + $data->setActionId(ActionsInterface::ACCOUNT_CREATE); + $data->setCreatedBy(1); + $data->setHash(self::AUTH_TOKEN_PASS); + $data->setUserId(2); + + self::$service->update($data); + + $data = self::$service->getTokenByToken(ActionsInterface::ACCOUNT_CREATE, $data->getToken()); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(ActionsInterface::ACCOUNT_CREATE, $data->getActionId()); + $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $data->getHash())); + $this->assertEquals(2, $data->getUserId()); + + $vault = Util::unserialize(Vault::class, $data->getVault()); + + $this->assertEquals('12345678900', $vault->getData(self::AUTH_TOKEN_PASS . $data->getToken())); + + $this->expectException(NoSuchItemException::class); + + $data->setId(10); + $data->setUserId(1); + + self::$service->update($data); + } + + /** + * @throws CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetById() + { + $data = self::$service->getById(1); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(1, $data->getId()); + $this->assertEquals(ActionsInterface::ACCOUNT_SEARCH, $data->getActionId()); + $this->assertEquals(pack('H*', '31326239303237643234656666663762666261636138626437373461346333346234356465333565303333643262313932613838663464666165653563323333'), $data->getToken()); + $this->assertNull($data->getHash()); + + $data = self::$service->getById(2); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(2, $data->getId()); + $this->assertEquals(ActionsInterface::ACCOUNT_VIEW_PASS, $data->getActionId()); + $this->assertEquals(self::AUTH_TOKEN, $data->getToken()); + $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $data->getHash())); + + $vault = Util::unserialize(Vault::class, $data->getVault()); + + $this->assertEquals('12345678900', $vault->getData(self::AUTH_TOKEN_PASS . $data->getToken())); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testSearch() + { + $itemSearchData = new ItemSearchData(); + $itemSearchData->setSeachString('admin'); + + $result = self::$service->search($itemSearchData); + $data = $result->getDataAsArray(); + + $this->assertEquals(4, $result->getNumRows()); + $this->assertCount(4, $data); + + $this->assertInstanceOf(\stdClass::class, $data[0]); + $this->assertEquals(ActionsInterface::ACCOUNT_SEARCH, $data[0]->actionId); + $this->assertEquals(self::AUTH_TOKEN, $data[0]->token); + + $this->assertInstanceOf(\stdClass::class, $data[1]); + $this->assertEquals(ActionsInterface::ACCOUNT_VIEW, $data[1]->actionId); + $this->assertEquals(self::AUTH_TOKEN, $data[1]->token); + + $itemSearchData = new ItemSearchData(); + $itemSearchData->setSeachString('test'); + + $result = self::$service->search($itemSearchData); + + $this->assertEquals(0, $result->getNumRows()); + $this->assertCount(0, $result->getDataAsArray()); + } + + /** + * @throws CryptoException + * @throws ServiceException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testCreate() + { + $authTokenData = new AuthTokenData(); + $authTokenData->setActionId(ActionsInterface::ACCOUNT_CREATE); + $authTokenData->setCreatedBy(1); + $authTokenData->setHash(self::AUTH_TOKEN_PASS); + $authTokenData->setUserId(2); + + $this->assertEquals(6, self::$service->create($authTokenData)); + $this->assertEquals(6, $this->conn->getRowCount('AuthToken')); + + $data = self::$service->getTokenByToken(ActionsInterface::ACCOUNT_CREATE, $authTokenData->getToken()); + + $this->assertInstanceOf(AuthTokenData::class, $data); + $this->assertEquals(ActionsInterface::ACCOUNT_CREATE, $data->getActionId()); + $this->assertTrue(Hash::checkHashKey(self::AUTH_TOKEN_PASS, $data->getHash())); + $this->assertEquals(6, $data->getId()); + $this->assertEquals(2, $data->getUserId()); + + $vault = Util::unserialize(Vault::class, $data->getVault()); + + $this->assertEquals('12345678900', $vault->getData(self::AUTH_TOKEN_PASS . $data->getToken())); + + $this->expectException(DuplicatedItemException::class); + + $authTokenData->setUserId(2); + + self::$service->create($authTokenData); + } +}