getContainer()->get('injectableFactory'); $this->factory = $injectableFactory->create(SelectBuilderFactory::class); } protected function initTest(array $aclData = [], bool $skipLogin = false, bool $isPortal = false) : Application { $this->createUser('tester', [ 'data' => $aclData, ]); if (!$skipLogin) { $this->auth('tester'); } $app = $this->createApplication(); $injectableFactory = $app->getContainer()->get('injectableFactory'); $this->factory = $injectableFactory->create(SelectBuilderFactory::class); $this->user = $app->getContainer()->get('user'); return $app; } protected function initTestPortal(array $aclData = [], bool $skipLogin = false) : Application { $app = $this->createApplication(); $em = $app->getContainer()->get('entityManager'); $this->contact = $em->createEntity('Contact', []); $this->account = $em->createEntity('Account', []); $this->portal = $em->createEntity('Portal', [ 'name' => 'Portal', ]); $this->createUser( [ 'userName' => 'tester', 'portalsIds' => [$this->portal->id], 'contactId' => $this->contact->id, 'accountsIds' => [$this->account->id], ], [ 'data' => $aclData, ], true ); if (!$skipLogin) { $this->auth('tester', null, $this->portal->id); } $app = $this->createApplication(); $injectableFactory = $app->getContainer()->get('injectableFactory'); $this->factory = $injectableFactory->create(SelectBuilderFactory::class); $container = $app->getContainer(); $this->user = $container->get('user'); return $app; } public function testBuild1() { $app = $this->initTest( [ 'Account' => [ 'read' => 'team', ], ] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $builder = $this->factory->create(); $searchParams = SearchParams::fromRaw([ 'orderBy' => 'name', 'order' => SearchParams::ORDER_DESC, 'primaryFilter' => 'customers', 'boolFilterList' => ['onlyMy'], 'where' => [ [ 'type' => 'equals', 'attribute' => 'name', 'value' => 'test', ], [ 'type' => 'before', 'attribute' => 'createdAt', 'value' => '2020-12-12 10:00', 'dateTime' => true, ], ], ]); $query = $builder ->from('Account') ->withStrictAccessControl() ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Account', 'orderBy' => [ [ 'name', 'DESC', ], [ 'id', 'DESC', ], ], 'whereClause' => [ 'id=s' => Select::fromRaw([ 'select' => [ 'id', ], 'from' => 'Account', 'leftJoins' => [ [ 'EntityTeam', 'entityTeam', [ 'entityTeam.entityId:' => 'id', 'entityTeam.entityType' => 'Account', 'entityTeam.deleted' => false, ], ], ], 'whereClause' => [ 'OR' => [ 'entityTeam.teamId' => [], 'assignedUserId' => $userId, ], ], ]), 'OR' => [ [ 'assignedUserId' => $userId, ], ], 'type' => 'Customer', [ 'name=' => 'test', ], [ 'createdAt<' => '2020-12-12 10:00:00', ], ], ]; $this->assertEquals($expected, $raw); } public function testBuild2() { $app = $this->initTest( [ 'Meeting' => [ 'read' => 'team', ], ] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $builder = $this->factory->create(); $query = $builder ->from('Meeting') ->withStrictAccessControl() ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Meeting', 'whereClause' => [ 'id=s' => Select::fromRaw([ 'select' => [ 0 => 'id', ], 'from' => 'Meeting', 'leftJoins' => [ 0 => [ 0 => 'EntityTeam', 1 => 'entityTeam', 2 => [ 'entityTeam.entityId:' => 'id', 'entityTeam.entityType' => 'Meeting', 'entityTeam.deleted' => false, ], ], 1 => [ 0 => 'MeetingUser', 1 => 'usersMiddle', 2 => [ 'usersMiddle.meetingId:' => 'id', 'usersMiddle.deleted' => false, ], ], ], 'whereClause' => [ 'OR' => [ 0 => [ 'entityTeam.teamId=' => [], ], 1 => [ 'usersMiddle.userId=' => $userId, ], 2 => [ 'assignedUserId=' => $userId, ], ], ], ]), ], ]; $this->assertEquals($expected, $raw); } public function testEmailAccessFilterOnlyOwn() { $app = $this->initTest( [ 'Email' => [ 'read' => 'own', ], ] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $builder = $this->factory->create(); $query = $builder ->from('Email') ->withStrictAccessControl() ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Email', 'leftJoins' => [ 0 => [ 0 => 'EmailUser', 1 => 'emailUser', 2 => [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $userId, ], ], ], 'whereClause' => [ 'emailUser.userId' => $userId, ] ]; $this->assertEquals($expected, $raw); } public function testEmailAccessFilterOnlyTeam() { $app = $this->initTest( [ 'Email' => [ 'read' => 'team', ], ] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $builder = $this->factory->create(); $query = $builder ->from('Email') ->withStrictAccessControl() ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Email', 'whereClause' => [ 'id=s' => Select::fromRaw([ 'select' => [ 0 => 'id', ], 'from' => 'Email', 'leftJoins' => [ 0 => [ 0 => 'EntityTeam', 1 => 'entityTeam', 2 => [ 'entityTeam.entityId:' => 'id', 'entityTeam.entityType' => 'Email', 'entityTeam.deleted' => false, ], ], 1 => [ 0 => 'EmailUser', 1 => 'emailUser', 2 => [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $userId, ], ], ], 'whereClause' => [ 'OR' => [ 'entityTeam.teamId' => [], 'emailUser.userId' => $userId, ], ], ]), ], ]; $this->assertEquals($expected, $raw); } public function testEmailAccessFilterOnlyAccount() { $this->initTestPortal( [ 'Email' => [ 'read' => 'account', ], ] ); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withStrictAccessControl() ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Email', 'joins' => [], 'leftJoins' => [ [ 'EmailUser', 'emailUser', [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $this->user->id, ] ], ], 'whereClause' => [ 'OR' => [ 'emailUser.userId' => $this->user->id, 'accountId' => [$this->account->id], [ 'parentType' => 'Contact', 'parentId' => $this->contact->id, ] ], ], ]; $this->assertEquals($expected['whereClause'], $raw['whereClause']); $this->assertEquals($expected['leftJoins'], $raw['leftJoins']); } public function testEmailAccessFilterOnlyContact() { $this->initTestPortal( [ 'Email' => [ 'read' => 'contact', ], ] ); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withStrictAccessControl() ->build(); $raw = $query->getRaw(); $expected = [ 'from' => 'Email', 'joins' => [], 'leftJoins' => [ [ 'EmailUser', 'emailUser', [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $this->user->id, ] ], ], 'whereClause' => [ 'OR' => [ 'emailUser.userId' => $this->user->id, [ 'parentType' => 'Contact', 'parentId' => $this->contact->id, ] ], ], ]; $this->assertEquals($expected['whereClause'], $raw['whereClause']); $this->assertEquals($expected['leftJoins'], $raw['leftJoins']); } public function testBuildDefaultOrder() { $this->initTest( [] ); $searchParams = SearchParams::fromRaw([]); $builder = $this->factory->create(); $query = $builder ->from('Meeting') ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $expectedOrderBy = [ ['dateStart', 'DESC'], ['id', 'DESC'], ]; $this->assertEquals($expectedOrderBy, $raw['orderBy']); } public function testBuildMeetingDateTime() { $this->initTest( [] ); $searchParams = SearchParams::fromRaw([ 'where' => [ [ 'type' => 'on', 'attribute' => 'dateStart', 'value' => '2020-12-12', 'dateTime' => true, ], ], ]); $builder = $this->factory->create(); $query = $builder ->from('Meeting') ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'OR' => [ [ 'dateStartDate=' => '2020-12-12', ], [ 'AND' => [ [ 'AND' => [ 'dateStart>=' => '2020-12-12 00:00:00', 'dateStart<=' => '2020-12-12 23:59:59', ], ], [ 'dateStartDate=' => null, ], ], ], ], ]; $this->assertEquals($expectedWhereClause, $raw['whereClause']); } public function testEmailInbox() { $app = $this->initTest( [] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $emailAddressId = $this->createUserEmailAddress($container); $searchParams = SearchParams::fromRaw([ 'where' => [ [ 'type' => 'inFolder', 'attribute' => 'folderId', 'value' => 'inbox', ], ], ]); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withSearchParams($searchParams) ->withAdditionalApplierClassNameList([ EmailAdditionalApplier::class, ]) ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'emailUser.inTrash' => false, 'emailUser.folderId' => null, 'emailUser.userId' => $userId, [ 'status' => ['Archived', 'Sent'], 'groupFolderId' => null, ], 'fromEmailAddressId!=' => [$emailAddressId], [ 'OR' => [ 'status' => 'Archived', 'createdById!=' => $userId, ], ], ]; $expectedLeftJoins = [ [ 'EmailUser', 'emailUser', [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $this->user->id, ], ], ]; $expectedSelect = [ '*', ['emailUser.isRead', 'isRead'], ['emailUser.isImportant', 'isImportant'], ['emailUser.inTrash', 'inTrash'], ['emailUser.folderId', 'folderId'], ]; $expectedUseIndex = ['dateSent']; $this->assertEquals($expectedWhereClause, $raw['whereClause']); $this->assertEquals($expectedLeftJoins, $raw['leftJoins']); $this->assertEquals($expectedSelect, $raw['select']); $this->assertEquals($expectedUseIndex, $raw['useIndex']); } public function testEmailSent() { $app = $this->initTest( [] ); $container = $app->getContainer(); $userId = $container->get('user')->id; $emailAddressId = $this->createUserEmailAddress($container); $searchParams = SearchParams::fromRaw([ 'where' => [ [ 'type' => 'inFolder', 'attribute' => 'folderId', 'value' => 'sent', ], ], ]); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'OR' => [ 'fromEmailAddressId' => [$emailAddressId], [ 'status' => 'Sent', 'createdById' => $userId, ] ], [ 'status!=' => 'Draft', ], 'emailUser.inTrash' => false, ]; $expectedLeftJoins = [ [ 'EmailUser', 'emailUser', [ 'emailUser.emailId:' => 'id', 'emailUser.deleted' => false, 'emailUser.userId' => $this->user->id, ], ], ]; $this->assertEquals($expectedWhereClause, $raw['whereClause']); $this->assertEquals($expectedLeftJoins, $raw['leftJoins']); } public function testEmailEmailAddressEquals() { $app = $this->initTest( [] ); $em = $app->getContainer()->get('entityManager'); $emailAddress = $em->createEntity('EmailAddress', [ 'name' => 'test@test.com', ]); $searchParams = SearchParams::fromRaw([ 'where' => [ [ 'type' => 'equals', 'attribute' => 'emailAddress', 'value' => 'test@test.com', ], ], ]); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $this->assertEquals($emailAddress->id, $raw['whereClause']['OR']['fromEmailAddressId']); } public function testEmailFromEquals() { $app = $this->initTest(); $em = $app->getContainer()->get('entityManager'); $emailAddress = $em->createEntity('EmailAddress', [ 'name' => 'test@test.com', ]); $searchParams = SearchParams::fromRaw([ 'where' => [ [ 'type' => 'equals', 'attribute' => 'from', 'value' => 'test@test.com', ], ], ]); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withSearchParams($searchParams) ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'fromEmailAddressId' => $emailAddress->id, ]; $this->assertEquals($expectedWhereClause, $raw['whereClause']); } public function testEmailBoolOnlyMy() { $this->initTest(); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withBoolFilter('onlyMy') ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'OR' => [ [ 'emailUser.userId' => $this->user->id, ], ], ]; $this->assertEquals($expectedWhereClause, $raw['whereClause']); } public function testEmailTextSearch1() { $app = $this->initTest(); $emailAddressId = $this->createUserEmailAddress($app->getContainer()); $builder = $this->factory->create(); $query = $builder ->from('Email') ->withTextFilter('test@test.com') ->build(); $raw = $query->getRaw(); $expectedWhereClause = [ 'OR' => [ ['NOT_EQUAL:(MATCH_NATURAL_LANGUAGE:(name, bodyPlain, body, \'test@test.com\'), 0):' => null], ['fromEmailAddressId=' => $emailAddressId], ['emailEmailAddress.emailAddressId=' => $emailAddressId], ], ]; $this->assertEquals($expectedWhereClause, $raw['whereClause']); } protected function createUserEmailAddress(Container $container) : string { $userId = $container->get('user')->id; $em = $container->get('entityManager'); $user = $em->getEntity('User', $userId); $emailAddress = $em->createEntity('EmailAddress', [ 'name' => 'test@test.com', ]); $em ->getRepository('User') ->getRelation($user, 'emailAddresses') ->relate($emailAddress); return $emailAddress->id; } }