. */ namespace SP\Tests\Domain\Account\Services; use PHPUnit\Framework\MockObject\Builder\InvocationStubber; use PHPUnit\Framework\MockObject\MockObject; use RuntimeException; use SP\DataModel\UserData; use SP\DataModel\UserGroupData; use SP\Domain\Account\Ports\AccountSearchDataBuilderInterface; use SP\Domain\Account\Ports\AccountSearchRepositoryInterface; use SP\Domain\Account\Search\AccountSearchConstants; use SP\Domain\Account\Search\AccountSearchFilter; use SP\Domain\Account\Services\AccountSearchService; use SP\Domain\User\Ports\UserGroupServiceInterface; use SP\Domain\User\Ports\UserServiceInterface; use SP\Infrastructure\Database\QueryResult; use SP\Tests\Domain\Account\Search\AccountSearchTokenizerDataTrait; use SP\Tests\UnitaryTestCase; /** * Class AccountSearchServiceTest * * @group unitary */ class AccountSearchServiceTest extends UnitaryTestCase { use AccountSearchTokenizerDataTrait; private AccountSearchRepositoryInterface|MockObject $accountSearchRepository; private AccountSearchService $accountSearchService; private AccountSearchDataBuilderInterface|MockObject $accountSearchDataBuilder; /** * @dataProvider searchUsingStringDataProvider * * @throws \SP\Core\Exceptions\QueryException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\SPException */ public function testGetByFilter(string $search) { $accountSearchFilter = AccountSearchFilter::build($search); $queryResult = new QueryResult(); $this->accountSearchRepository ->expects(self::once()) ->method('getByFilter') ->with($accountSearchFilter) ->willReturn($queryResult); $this->accountSearchDataBuilder ->expects(self::once()) ->method('buildFrom'); $this->accountSearchService->getByFilter($accountSearchFilter); } /** * @dataProvider searchByItemDataProvider * * @throws \SP\Core\Exceptions\QueryException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\SPException */ public function testGetByFilterUsingItems(string $search, array $expected) { $accountSearchFilter = AccountSearchFilter::build($search); $queryResult = new QueryResult(); $this->accountSearchRepository ->expects(self::once()) ->method('getByFilter') ->with($accountSearchFilter) ->willReturn($queryResult); $this->accountSearchDataBuilder ->expects(self::once()) ->method('buildFrom'); $this->buildExpectationForFilter(array_keys($expected)[0]); $this->accountSearchService->getByFilter($accountSearchFilter); } private function buildExpectationForFilter(string $filter): InvocationStubber { switch ($filter) { case AccountSearchConstants::FILTER_USER_NAME: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForUser'); case AccountSearchConstants::FILTER_OWNER: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForOwner'); case AccountSearchConstants::FILTER_GROUP_NAME: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForGroup'); case AccountSearchConstants::FILTER_MAIN_GROUP: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForMainGroup'); case AccountSearchConstants::FILTER_FILE_NAME: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForFile'); case AccountSearchConstants::FILTER_ACCOUNT_ID: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForAccountId'); case AccountSearchConstants::FILTER_CLIENT_NAME: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForClient'); case AccountSearchConstants::FILTER_CATEGORY_NAME: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForCategory'); case AccountSearchConstants::FILTER_ACCOUNT_NAME_REGEX: return $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForAccountNameRegex'); } throw new RuntimeException('Invalid filter'); } /** * @dataProvider searchByItemDataProvider * * @throws \SP\Core\Exceptions\QueryException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\SPException */ public function testGetByFilterUsingItemsDoesNotThrowException(string $search, array $expected) { $accountSearchFilter = AccountSearchFilter::build($search); $queryResult = new QueryResult(); $this->accountSearchRepository ->expects(self::once()) ->method('getByFilter') ->with($accountSearchFilter) ->willReturn($queryResult); $this->accountSearchDataBuilder ->expects(self::once()) ->method('buildFrom'); $mock = $this->buildExpectationForFilter(array_keys($expected)[0]); $mock->willThrowException(new RuntimeException('test')); $this->accountSearchService->getByFilter($accountSearchFilter); } /** * @dataProvider searchByConditionDataProvider * * @throws \SP\Core\Exceptions\QueryException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\SPException */ public function testGetByFilterUsingConditions(string $search, array $expected) { $accountSearchFilter = AccountSearchFilter::build($search); $queryResult = new QueryResult(); $this->accountSearchRepository ->expects(self::once()) ->method('getByFilter') ->with($accountSearchFilter) ->willReturn($queryResult); $this->accountSearchDataBuilder ->expects(self::once()) ->method('buildFrom'); $this->buildExpectationForCondition(array_keys($expected)[0]); $this->accountSearchService->getByFilter($accountSearchFilter); } private function buildExpectationForCondition(string $condition) { switch ($condition) { case AccountSearchConstants::FILTER_IS_EXPIRED: $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForIsExpired'); break; case AccountSearchConstants::FILTER_NOT_EXPIRED: $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForIsNotExpired'); break; case AccountSearchConstants::FILTER_IS_PRIVATE: $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForIsPrivate') ->with($this->context->getUserData()->getId(), $this->context->getUserData()->getUserGroupId()); break; case AccountSearchConstants::FILTER_NOT_PRIVATE: $this->accountSearchRepository ->expects(self::once()) ->method('withFilterForIsNotPrivate'); break; } } protected function setUp(): void { parent::setUp(); $userService = $this->createMock(UserServiceInterface::class); $userService ->method('getByLogin') ->willReturn(new UserData([ 'id' => self::$faker->randomNumber(), 'userGroupId' => self::$faker->randomNumber(), ])); $userGroupService = $this->createMock(UserGroupServiceInterface::class); $userGroupService ->method('getByName') ->willReturn(new UserGroupData([ 'id' => self::$faker->randomNumber(), ])); $this->accountSearchRepository = $this->createMock(AccountSearchRepositoryInterface::class); $this->accountSearchDataBuilder = $this->createMock(AccountSearchDataBuilderInterface::class); $this->accountSearchService = new AccountSearchService( $this->application, $userService, $userGroupService, $this->accountSearchRepository, $this->accountSearchDataBuilder ); } }