Skip to content

Commit e4cb689

Browse files
Merge remote-tracking branch 'ibexa/4.0' into main
2 parents d6f34d2 + 12d44a4 commit e4cb689

File tree

5 files changed

+107
-18
lines changed

5 files changed

+107
-18
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"behat/behat": "^3.6.1",
6363
"jenner/simple_fork": "^1.2",
6464
"friends-of-behat/mink-extension": "^2.4",
65+
"league/flysystem-memory": "^1.0",
6566
"ibexa/ci-scripts": "^0.2@dev",
6667
"ibexa/code-style": "^1.0",
6768
"phpunit/phpunit": "^8.2",

src/contracts/Test/IbexaTestKernel.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
use Ibexa\Contracts\Core\Persistence\TransactionHandler;
1717
use Ibexa\Contracts\Core\Repository;
1818
use Ibexa\Contracts\Core\Test\Persistence\Fixture\YamlFixture;
19+
use Ibexa\Core\IO\Adapter\LocalAdapter;
1920
use JMS\TranslationBundle\JMSTranslationBundle;
21+
use League\Flysystem\Memory\MemoryAdapter;
2022
use Liip\ImagineBundle\LiipImagineBundle;
2123
use Psr\Log\NullLogger;
2224
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
@@ -150,6 +152,7 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
150152
$this->loadServices($loader);
151153

152154
$loader->load(static function (ContainerBuilder $container): void {
155+
self::prepareIOServices($container);
153156
self::createPublicAliasesForServicesUnderTest($container);
154157
self::setUpTestLogger($container);
155158
});
@@ -195,6 +198,11 @@ private static function getResourcesPath(): string
195198
return dirname(__DIR__, 3) . '/tests/bundle/Core/Resources';
196199
}
197200

201+
private static function prepareIOServices(ContainerBuilder $container): void
202+
{
203+
$container->setDefinition(LocalAdapter::class, new Definition(MemoryAdapter::class));
204+
}
205+
198206
private static function createPublicAliasesForServicesUnderTest(ContainerBuilder $container): void
199207
{
200208
foreach (static::getExposedServicesByClass() as $className) {

src/lib/FieldType/EmailAddress/SearchField.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public function getIndexData(Field $field, FieldDefinition $fieldDefinition)
3030
new Search\FieldType\FullTextField([
3131
'space_normalize',
3232
'latin1_lowercase',
33+
'ascii_lowercase',
34+
'cyrillic_lowercase',
35+
'greek_lowercase',
36+
'latin_lowercase',
37+
'latin-exta_lowercase',
3338
], false)
3439
),
3540
];

src/lib/Search/Legacy/Content/WordIndexer/Gateway/DoctrineDatabase.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ private function indexWords(FullTextData $fullTextData, array $indexArray, array
244244

245245
for ($i = 0; $i < count($indexArray); ++$i) {
246246
$indexWord = $indexArray[$i]['Word'];
247+
$indexWord = $this->transformationProcessor->transformByGroup($indexWord, 'lowercase');
247248
$contentFieldId = $indexArray[$i]['ContentClassAttributeID'];
248249
$identifier = $indexArray[$i]['identifier'];
249250
$integerValue = $indexArray[$i]['integer_value'];
@@ -257,6 +258,7 @@ private function indexWords(FullTextData $fullTextData, array $indexArray, array
257258

258259
if (isset($indexArray[$i + 1])) {
259260
$nextIndexWord = $indexArray[$i + 1]['Word'];
261+
$nextIndexWord = $this->transformationProcessor->transformByGroup($nextIndexWord, 'lowercase');
260262
$nextWordId = $wordIDArray[$nextIndexWord];
261263
} else {
262264
$nextWordId = 0;

tests/integration/Core/Repository/SearchEngineIndexingTest.php

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
use DateTime;
1010
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
1111
use Ibexa\Contracts\Core\Repository\SearchService;
12+
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
1213
use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
1314
use Ibexa\Contracts\Core\Repository\Values\Content\LocationQuery;
1415
use Ibexa\Contracts\Core\Repository\Values\Content\Query;
1516
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
17+
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
1618

1719
/**
1820
* Test case for indexing operations with a search engine.
@@ -827,13 +829,59 @@ public function testIndexingSpecialFullTextCases($text, $searchForText)
827829
$query = new Query(['filter' => $criterion]);
828830
$result = $searchService->findContent($query);
829831

832+
$found = false;
830833
// for some cases there might be more than one hit, so check if proper one was found
831834
foreach ($result->searchHits as $searchHit) {
832835
if ($content->contentInfo->id === $searchHit->valueObject->versionInfo->contentInfo->id) {
833-
return;
836+
$found = true;
837+
break;
838+
}
839+
}
840+
841+
self::assertTrue($found, 'Failed to find required Content in search results');
842+
}
843+
844+
/**
845+
* Check if FullText indexing works for email addresses.
846+
*
847+
* @dataProvider getEmailAddressesCases
848+
*/
849+
public function testIndexingEmailFieldCases(string $email, string $searchForText): void
850+
{
851+
$repository = $this->getRepository();
852+
$searchService = $repository->getSearchService();
853+
854+
$content = $this->createContentEmailWithAddress($email, [2]);
855+
$this->refreshSearch($repository);
856+
857+
$criterion = new Criterion\FullText($searchForText);
858+
$query = new Query(['filter' => $criterion]);
859+
$result = $searchService->findContent($query);
860+
861+
$found = false;
862+
// for some cases there might be more than one hit, so check if proper one was found
863+
foreach ($result->searchHits as $searchHit) {
864+
if ($content->contentInfo->id === $searchHit->valueObject->versionInfo->contentInfo->id) {
865+
$found = true;
866+
break;
834867
}
835868
}
836-
$this->fail('Failed to find required Content in search results');
869+
870+
self::assertTrue($found, 'Failed to find required Content in search results');
871+
}
872+
873+
/**
874+
* Data Provider for {@see testIndexingSpecialFullTextCases()} method.
875+
*/
876+
public function getEmailAddressesCases(): array
877+
{
878+
return [
879+
['test@TEST.com', 'test@test.com'],
880+
['TEST3@TEST.com', 'test3@test.com'],
881+
['TeSt1@TEST.com', 'test1@test.com'],
882+
['TeSt2@TesT.com', 'test2@test.com'],
883+
['test4@test.com', 'test4@test.com'],
884+
];
837885
}
838886

839887
/**
@@ -1115,22 +1163,22 @@ public function testDeleteTranslation()
11151163
}
11161164

11171165
/**
1118-
* Will create if not exists a simple content type for test purposes with just one required field name.
1119-
*
1120-
* @return \Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType
1166+
* Will create if not exists a simple content type for test purposes with just one required field.
11211167
*/
1122-
protected function createTestContentType()
1123-
{
1168+
protected function createTestContentType(
1169+
string $identifier = 'name',
1170+
string $fieldTypeIdentifier = 'ezstring',
1171+
string $contentTypeIdentifier = 'test-type'
1172+
): ContentType {
11241173
$repository = $this->getRepository();
11251174
$contentTypeService = $repository->getContentTypeService();
1126-
$contentTypeIdentifier = 'test-type';
11271175
try {
11281176
return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
11291177
} catch (NotFoundException $e) {
11301178
// continue creation process
11311179
}
11321180

1133-
$nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
1181+
$nameField = $contentTypeService->newFieldDefinitionCreateStruct($identifier, $fieldTypeIdentifier);
11341182
$nameField->fieldGroup = 'main';
11351183
$nameField->position = 1;
11361184
$nameField->isTranslatable = true;
@@ -1156,30 +1204,55 @@ protected function createTestContentType()
11561204
* Will create and publish an content with a filed with a given content name in location provided into
11571205
* $parentLocationIdList.
11581206
*
1159-
* @param string $contentName
1160-
* @param array $parentLocationIdList
1207+
* @param int[] $parentLocationIdList
1208+
*/
1209+
protected function createContentWithName(string $contentName, array $parentLocationIdList = []): Content
1210+
{
1211+
$testableContentType = $this->createTestContentType();
1212+
1213+
return $this->createContent($testableContentType, $contentName, 'name', $parentLocationIdList);
1214+
}
1215+
1216+
/**
1217+
* Will create and publish an content with an email filed with a given content name in location provided into
1218+
* $parentLocationIdList.
11611219
*
1162-
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Content
1220+
* @param string $address
1221+
* @param int[] $parentLocationIdList
1222+
*
1223+
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
1224+
* @throws \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1225+
* @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException
1226+
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1227+
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
11631228
*/
1164-
protected function createContentWithName($contentName, array $parentLocationIdList = [])
1229+
protected function createContentEmailWithAddress(string $address, array $parentLocationIdList = []): Content
11651230
{
1231+
$testableContentType = $this->createTestContentType('email', 'ezemail', 'test-email-type');
1232+
1233+
return $this->createContent($testableContentType, $address, 'email', $parentLocationIdList);
1234+
}
1235+
1236+
protected function createContent(
1237+
ContentType $testableContentType,
1238+
string $contentName,
1239+
string $fieldDefIdentifier,
1240+
array $parentLocationIdList
1241+
): Content {
11661242
$contentService = $this->getRepository()->getContentService();
11671243
$locationService = $this->getRepository()->getLocationService();
11681244

1169-
$testableContentType = $this->createTestContentType();
1170-
11711245
$rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
1172-
$rootContentStruct->setField('name', $contentName);
1246+
$rootContentStruct->setField($fieldDefIdentifier, $contentName);
11731247

11741248
$parentLocationList = [];
11751249
foreach ($parentLocationIdList as $locationID) {
11761250
$parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
11771251
}
11781252

11791253
$contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
1180-
$publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
11811254

1182-
return $publishedContent;
1255+
return $contentService->publishVersion($contentDraft->getVersionInfo());
11831256
}
11841257

11851258
/**

0 commit comments

Comments
 (0)