Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kisztof committed Oct 19, 2023
1 parent a5b5db3 commit d8fb688
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ public function mapConfig(

$settings = $scopeSettings['search'];

$this->addAutocompleteParameters($settings, $currentScope, $contextualizer);
$this->addSuggestionParameters($settings, $currentScope, $contextualizer);
}

public function addSemanticConfig(NodeBuilder $nodeBuilder): void
{
$rootProductCatalogNode = $nodeBuilder->arrayNode('search');
$rootProductCatalogNode->append($this->addAutocompleteConfiguration());
$rootProductCatalogNode->append($this->addSuggestionConfiguration());
}

/**
* @param array<string, mixed> $settings
*/
private function addAutocompleteParameters(
private function addSuggestionParameters(
$settings,
string $currentScope,
ContextualizerInterface $contextualizer
Expand All @@ -77,7 +77,7 @@ private function addAutocompleteParameters(
}
}

private function addAutocompleteConfiguration(): ArrayNodeDefinition
private function addSuggestionConfiguration(): ArrayNodeDefinition
{
$treeBuilder = new TreeBuilder('suggestion');
$node = $treeBuilder->getRootNode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

use Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException;
use Ibexa\Contracts\Core\Repository\Values\Content\Query;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\FullText;
use Ibexa\Core\Repository\SiteAccessAware\SearchService;
use Ibexa\Search\EventDispatcher\Event\ContentSuggestion;
use Ibexa\Search\Mapper\SearchHitToContentSuggestionMapper;
Expand Down Expand Up @@ -49,7 +48,7 @@ public function onContentSuggestion(ContentSuggestion $event): ContentSuggestion
$limit = $query->getLimit();
$language = $query->getLanguage();

$criterion = new FullText($value);
$criterion = new Query\Criterion\FullText($value);
$query = new Query(['filter' => $criterion, 'limit' => $limit]);

try {
Expand Down
5 changes: 3 additions & 2 deletions src/lib/Mapper/SearchHitToContentSuggestionMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ public function __construct(ConfigResolverInterface $configResolver)

public function map(SearchHit $searchHit): ContentSuggestion
{
$content = $searchHit->getValueObject();
/** @var \Ibexa\Contracts\Core\Repository\Values\ValueObject $content */
$content = $searchHit->valueObject;

$rootLocationId = $this->configResolver->getParameter('content.tree_root.location_id');

$parentsLocation = $content->contentInfo->mainLocation->path;
$parentsLocation = $content->versionInfo->contentInfo->mainLocation->path;
$position = array_search((string)$rootLocationId, $parentsLocation);
if ($position !== false) {
$parentsLocation = array_slice($parentsLocation, $position);
Expand Down
21 changes: 20 additions & 1 deletion src/lib/Model/Suggestion/SuggestionCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,28 @@

/**
* @template-extends \Ibexa\Contracts\Core\Collection\MutableArrayList<
* \Ibexa\Search\Model\Suggestion\ContentSuggestion
* \Ibexa\Search\Model\Suggestion\Suggestion
* |\Ibexa\Search\Model\Suggestion\ContentSuggestion
* >
*/
final class SuggestionCollection extends MutableArrayList
{
/**
* @param Suggestion $item
*/
public function append($item): void
{
if (!$item instanceof Suggestion) {
throw new \TypeError(
\sprintf(
'Argument 1 passed to %s::append() must be an instance of %s, %s given',
__CLASS__,
Suggestion::class,
\is_object($item) ? \get_class($item) : \gettype($item)
)
);
}

parent::append($item);
}
}
3 changes: 2 additions & 1 deletion src/lib/Service/Event/SuggestionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Ibexa\Contracts\Search\Event\AfterSuggestionEvent;
use Ibexa\Contracts\Search\Event\BeforeSuggestionEvent;
use Ibexa\Contracts\Search\Service\Decorator\SuggestionServiceDecorator;
use Ibexa\Contracts\Search\Service\SuggestionServiceInterface;
use Ibexa\Search\Model\Suggestion\SuggestionCollection;
use Ibexa\Search\Model\SuggestionQuery;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
Expand All @@ -20,7 +21,7 @@ final class SuggestionService extends SuggestionServiceDecorator
private EventDispatcherInterface $eventDispatcher;

public function __construct(
SuggestionServiceDecorator $innerService,
SuggestionServiceInterface $innerService,
EventDispatcherInterface $eventDispatcher
) {
parent::__construct($innerService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/**
* @covers \Ibexa\Bundle\Search\DependencyInjection\Configuration\Parser\SiteAccessAware\SuggestionParser
*/
final class AutocompleteParserTest extends AbstractParserTestCase
final class SuggestionParserTest extends AbstractParserTestCase
{
protected function getContainerExtensions(): array
{
Expand Down
67 changes: 67 additions & 0 deletions tests/lib/Mapper/SearchHitToContentSuggestionMapperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Search\Mapper;

use Ibexa\Contracts\Core\Persistence\Content\ContentInfo;
use Ibexa\Contracts\Core\Persistence\Content\Location;
use Ibexa\Contracts\Core\Persistence\Content\VersionInfo;
use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchHit;
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Ibexa\Core\Repository\Values\Content\Content;
use Ibexa\Core\Repository\Values\ContentType\ContentType;
use Ibexa\Search\Mapper\SearchHitToContentSuggestionMapper;
use Ibexa\Search\Model\Suggestion\ContentSuggestion;
use PHPUnit\Framework\TestCase;

final class SearchHitToContentSuggestionMapperTest extends TestCase
{
public function testMap(): void
{
$this->markTestIncomplete('This test has not been implemented yet.');

$mapper = new SearchHitToContentSuggestionMapper(
$this->getConfigResolverMock()
);

$result = $mapper->map(
new SearchHit([
'valueObject' => new Content([
'id' => 1,
'contentInfo' => new ContentInfo([
'name' => 'name',
'mainLanguageCode' => 'eng-GB',
'mainLocation' => new Location([
'pathString' => [1, 2, 3],
]),
'contentTypeId' => 1,
]),
'versionInfo' => new VersionInfo([
'contentInfo' => new ContentInfo([
'name' => 'name',
'mainLanguageCode' => 'eng-GB',
'contentTypeId' => 1,
]),
]),
'contentType' => new ContentType([
'identifier' => 'content_type_identifier',
]),
]),
])
);
$this->assertInstanceOf(ContentSuggestion::class, $result);
}

private function getConfigResolverMock(): ConfigResolverInterface
{
$configResolverMock = $this->createMock(ConfigResolverInterface::class);
$configResolverMock->method('getParameter')->willReturn(5);

return $configResolverMock;
}
}
36 changes: 36 additions & 0 deletions tests/lib/Model/Suggestion/ContentSuggestionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Search\Model\Suggestion;

use Ibexa\Search\Model\Suggestion\ContentSuggestion;
use Ibexa\Search\Model\Suggestion\Suggestion;
use Ibexa\Tests\Core\Search\TestCase;

final class ContentSuggestionTest extends TestCase
{
public function testCreate(): void
{
$implementation = new ContentSuggestion(
1,
'content_type_identifier',
'name',
'text',
[0 => 'text']
);

$this->assertInstanceOf(Suggestion::class, $implementation);
$this->assertSame(1, $implementation->getContentId());
$this->assertSame('content_type_identifier', $implementation->getContentTypeIdentifier());
$this->assertSame('content', $implementation->getType());
$this->assertSame([0 => 'text'], $implementation->getParentsLocation());

$implementation->addPath(1, 'text2');
$this->assertSame([0 => 'text', 1 => 'text2'], $implementation->getParentsLocation());
}
}
36 changes: 36 additions & 0 deletions tests/lib/Model/Suggestion/SuggestionCollectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Search\Model\Suggestion;

use Ibexa\Contracts\Core\Collection\MutableArrayList;
use Ibexa\Search\Model\Suggestion\ContentSuggestion;
use Ibexa\Search\Model\Suggestion\SuggestionCollection;
use PHPUnit\Framework\TestCase;

final class SuggestionCollectionTest extends TestCase
{
public function testCollection(): void
{
$collection = new SuggestionCollection();
$this->assertInstanceOf(MutableArrayList::class, $collection);
$this->assertInstanceOf(SuggestionCollection::class, $collection);

$collection->append(new ContentSuggestion(1, 'article', 'test'));
$collection->append(new ContentSuggestion(2, 'article', 'test2'));

$this->assertCount(2, $collection);

foreach ($collection as $item) {
$this->assertInstanceOf(ContentSuggestion::class, $item);
}

$this->expectException(\TypeError::class);
$collection->append(new \stdClass());
}
}
34 changes: 34 additions & 0 deletions tests/lib/Model/Suggestion/SuggestionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Search\Model\Suggestion;

use Ibexa\Search\Model\Suggestion\Suggestion as SuggestionAlias;
use PHPUnit\Framework\TestCase;

final class SuggestionTest extends TestCase
{
public function testSuggestionCreate(): void
{
$implementation = new class('name', 'text', [0 => 'text']) extends SuggestionAlias {
public function getType(): string
{
return 'test_implementation';
}
};

$this->assertInstanceOf(SuggestionAlias::class, $implementation);
$this->assertSame('name', $implementation->getName());
$this->assertSame('text', $implementation->getPathString());
$this->assertSame([0 => 'text'], $implementation->getParentsLocation());
$this->assertSame('test_implementation', $implementation->getType());

$implementation->addPath(1, 'text2');
$this->assertSame([0 => 'text', 1 => 'text2'], $implementation->getParentsLocation());
}
}
99 changes: 99 additions & 0 deletions tests/lib/Service/Event/SuggestionServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Search\Service\Event;

use Ibexa\Contracts\Search\Event\AfterSuggestionEvent;
use Ibexa\Contracts\Search\Event\BeforeSuggestionEvent;
use Ibexa\Contracts\Search\Service\SuggestionServiceInterface;
use Ibexa\Search\Model\Suggestion\SuggestionCollection;
use Ibexa\Search\Model\SuggestionQuery;
use Ibexa\Search\Service\Event\SuggestionService;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

final class SuggestionServiceTest extends TestCase
{
public function testSuggestion(): void
{
$eventDispatcherMock = $this->getEventDispatcherMock();
$eventDispatcherMock
->method('dispatch')
->withConsecutive(
[
$this->isInstanceOf(BeforeSuggestionEvent::class),
],
[
$this->isInstanceOf(AfterSuggestionEvent::class),
]
)
->willReturnCallback(
static function ($event) {
return $event;
}
);

$innerServiceMock = $this->getSuggestionServiceMock();
$innerServiceMock
->method('suggest')
->willReturn(new SuggestionCollection());

$service = new SuggestionService($innerServiceMock, $eventDispatcherMock);

$result = $service->suggest(new SuggestionQuery('query', 10, 'eng-GB'));
self::assertInstanceOf(SuggestionCollection::class, $result);
}

public function testSuggestionStopPropagation(): void
{
$eventDispatcherMock = $this->getEventDispatcherMock();
$eventDispatcherMock
->expects(self::once())
->method('dispatch')
->withConsecutive(
[
$this->isInstanceOf(BeforeSuggestionEvent::class),
]
)
->willReturnCallback(
static function (BeforeSuggestionEvent $event) {
$event->stopPropagation();

return $event;
}
);

$innerServiceMock = $this->getSuggestionServiceMock();
$innerServiceMock
->method('suggest')
->willReturn(new SuggestionCollection());

$service = new SuggestionService($innerServiceMock, $eventDispatcherMock);

$result = $service->suggest(new SuggestionQuery('query', 10, 'eng-GB'));
self::assertInstanceOf(SuggestionCollection::class, $result);
}

private function getSuggestionServiceMock(): SuggestionServiceInterface
{
$suggestionServiceMock = $this->getMockBuilder(SuggestionServiceInterface::class)
->disableOriginalConstructor()
->getMock();

return $suggestionServiceMock;
}

private function getEventDispatcherMock(): EventDispatcherInterface
{
$eventDispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)
->disableOriginalConstructor()
->getMock();

return $eventDispatcherMock;
}
}
Loading

0 comments on commit d8fb688

Please sign in to comment.