Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[WIP] Add unit tests
  • Loading branch information
meyerbaptiste committed Dec 7, 2018
1 parent 8cd6fd9 commit 0aa292b
Show file tree
Hide file tree
Showing 25 changed files with 984 additions and 64 deletions.
2 changes: 1 addition & 1 deletion .php_cs.dist
Expand Up @@ -13,7 +13,7 @@ HEADER;

$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude('tests/Fixtures/app/cache')
->exclude('tests/Fixtures/app/var/cache')
;

return PhpCsFixer\Config::create()
Expand Down
14 changes: 7 additions & 7 deletions src/Bridge/Elasticsearch/DataProvider/CollectionDataProvider.php
Expand Up @@ -32,18 +32,18 @@
final class CollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $client;
private $indexMetadataFactory;
private $documentMetadataFactory;
private $denormalizer;
private $pagination;
private $collectionExtensions;

/**
* @param FullBodySearchCollectionExtensionInterface[] $collectionExtensions
*/
public function __construct(Client $client, DocumentMetadataFactoryInterface $indexMetadataFactory, DenormalizerInterface $denormalizer, Pagination $pagination, iterable $collectionExtensions = [])
public function __construct(Client $client, DocumentMetadataFactoryInterface $documentMetadataFactory, DenormalizerInterface $denormalizer, Pagination $pagination, iterable $collectionExtensions = [])
{
$this->client = $client;
$this->indexMetadataFactory = $indexMetadataFactory;
$this->documentMetadataFactory = $documentMetadataFactory;
$this->denormalizer = $denormalizer;
$this->pagination = $pagination;
$this->collectionExtensions = $collectionExtensions;
Expand All @@ -55,7 +55,7 @@ public function __construct(Client $client, DocumentMetadataFactoryInterface $in
public function supports(string $resourceClass, ?string $operationName = null, array $context = []): bool
{
try {
$this->indexMetadataFactory->create($resourceClass);
$this->documentMetadataFactory->create($resourceClass);
} catch (IndexNotFoundException $e) {
return false;
}
Expand All @@ -68,7 +68,7 @@ public function supports(string $resourceClass, ?string $operationName = null, a
*/
public function getCollection(string $resourceClass, ?string $operationName = null, array $context = [])
{
$indexMetadata = $this->indexMetadataFactory->create($resourceClass);
$documentMetadata = $this->documentMetadataFactory->create($resourceClass);
$body = [];

foreach ($this->collectionExtensions as $collectionExtension) {
Expand All @@ -95,8 +95,8 @@ public function getCollection(string $resourceClass, ?string $operationName = nu
}

$documents = $this->client->search([
'index' => $indexMetadata->getIndex(),
'type' => $indexMetadata->getType(),
'index' => $documentMetadata->getIndex(),
'type' => $documentMetadata->getType(),
'body' => $body,
]);

Expand Down
Expand Up @@ -17,6 +17,7 @@
use ApiPlatform\Core\Bridge\Elasticsearch\Util\FieldDatatypeTrait;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

/**
* Applies selected sorting while querying resource collection.
Expand All @@ -35,12 +36,14 @@ final class SortExtension implements FullBodySearchCollectionExtensionInterface
private $defaultDirection;
private $identifierExtractor;
private $resourceMetadataFactory;
private $nameConverter;

public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IdentifierExtractorInterface $identifierExtractor, PropertyMetadataFactoryInterface $propertyMetadataFactory, ?string $defaultDirection = null)
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IdentifierExtractorInterface $identifierExtractor, PropertyMetadataFactoryInterface $propertyMetadataFactory, ?NameConverterInterface $nameConverter = null, ?string $defaultDirection = null)
{
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->identifierExtractor = $identifierExtractor;
$this->propertyMetadataFactory = $propertyMetadataFactory;
$this->nameConverter = $nameConverter;
$this->defaultDirection = $defaultDirection;
}

Expand Down Expand Up @@ -85,9 +88,12 @@ private function getOrder(string $resourceClass, string $property, string $direc
$order = ['order' => strtolower($direction)];

if (null !== $nestedPath = $this->getNestedFieldPath($resourceClass, $property)) {
$nestedPath = null === $this->nameConverter ? $nestedPath : $this->nameConverter->normalize($property);
$order['nested'] = ['path' => $nestedPath];
}

$property = null === $this->nameConverter ? $property : $this->nameConverter->normalize($property);

return [$property => $order];
}
}
Expand Up @@ -20,6 +20,7 @@
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

/**
* Abstract class with helpers for easing the implementation of a filter.
Expand All @@ -34,12 +35,14 @@ abstract class AbstractFilter implements FilterInterface

protected $properties;
protected $propertyNameCollectionFactory;
protected $nameConverter;

public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, ?array $properties = null)
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, ?NameConverterInterface $nameConverter = null, ?array $properties = null)
{
$this->propertyNameCollectionFactory = $propertyNameCollectionFactory;
$this->propertyMetadataFactory = $propertyMetadataFactory;
$this->resourceClassResolver = $resourceClassResolver;
$this->nameConverter = $nameConverter;
$this->properties = $properties;
}

Expand All @@ -49,7 +52,7 @@ public function __construct(PropertyNameCollectionFactoryInterface $propertyName
protected function getProperties(string $resourceClass): \Traversable
{
if (null !== $this->properties) {
return yield from $this->properties;
return yield from array_keys($this->properties);
}

try {
Expand Down
9 changes: 6 additions & 3 deletions src/Bridge/Elasticsearch/DataProvider/Filter/OrderFilter.php
Expand Up @@ -16,6 +16,7 @@
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

/**
* Order the collection by given properties.
Expand All @@ -31,9 +32,9 @@ final class OrderFilter extends AbstractFilter implements SortFilterInterface
{
private $orderParameterName;

public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, string $orderParameterName = 'order', ?array $properties = null)
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, ?NameConverterInterface $nameConverter = null, string $orderParameterName = 'order', ?array $properties = null)
{
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $resourceClassResolver, $properties);
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $resourceClassResolver, $nameConverter, $properties);

$this->orderParameterName = $orderParameterName;
}
Expand All @@ -56,7 +57,7 @@ public function apply(array $clauseBody, string $resourceClass, ?string $operati
continue;
}

if (empty($direction) && null !== $defaultDirection = $this->properties[$property]['default_direction'] ?? null) {
if (empty($direction) && null !== $defaultDirection = $this->properties[$property] ?? null) {
$direction = $defaultDirection;
}

Expand All @@ -67,9 +68,11 @@ public function apply(array $clauseBody, string $resourceClass, ?string $operati
$order = ['order' => $direction];

if (null !== $nestedPath = $this->getNestedFieldPath($resourceClass, $property)) {
$nestedPath = null === $this->nameConverter ? $nestedPath : $this->nameConverter->normalize($nestedPath);
$order['nested'] = ['path' => $nestedPath];
}

$property = null === $this->nameConverter ? $property : $this->nameConverter->normalize($property);
$orders[] = [$property => $order];
}

Expand Down
12 changes: 8 additions & 4 deletions src/Bridge/Elasticsearch/DataProvider/Filter/TermFilter.php
Expand Up @@ -21,6 +21,7 @@
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

/**
* Filter the collection by given properties.
Expand All @@ -37,9 +38,9 @@ final class TermFilter extends AbstractFilter implements ConstantScoreFilterInte
private $iriConverter;
private $propertyAccessor;

public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, IdentifierExtractorInterface $identifierExtractor, IriConverterInterface $iriConverter, PropertyAccessorInterface $propertyAccessor, ?array $properties = null)
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, IdentifierExtractorInterface $identifierExtractor, IriConverterInterface $iriConverter, PropertyAccessorInterface $propertyAccessor, ?NameConverterInterface $nameConverter = null, ?array $properties = null)
{
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $resourceClassResolver, $properties);
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $resourceClassResolver, $nameConverter, $properties);

$this->identifierExtractor = $identifierExtractor;
$this->iriConverter = $iriConverter;
Expand Down Expand Up @@ -68,13 +69,16 @@ public function apply(array $clauseBody, string $resourceClass, ?string $operati
continue;
}

$convertedProperty = null === $this->nameConverter ? $property : $this->nameConverter->normalize($property);

if (1 === \count($values)) {
$term = ['term' => [$property => $values[0]]];
$term = ['term' => [$convertedProperty => $values[0]]];
} else {
$term = ['terms' => [$property => $values]];
$term = ['terms' => [$convertedProperty => $values]];
}

if (null !== $nestedPath = $this->getNestedFieldPath($resourceClass, $property)) {
$nestedPath = null === $this->nameConverter ? $nestedPath : $this->nameConverter->normalize($nestedPath);
$term = ['nested' => ['path' => $nestedPath, 'query' => $term]];
}

Expand Down
16 changes: 8 additions & 8 deletions src/Bridge/Elasticsearch/DataProvider/ItemDataProvider.php
Expand Up @@ -34,13 +34,13 @@
final class ItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
private $client;
private $indexMetadataFactory;
private $documentMetadataFactory;
private $denormalizer;

public function __construct(Client $client, DocumentMetadataFactoryInterface $indexMetadataFactory, DenormalizerInterface $denormalizer)
public function __construct(Client $client, DocumentMetadataFactoryInterface $documentMetadataFactory, DenormalizerInterface $denormalizer)
{
$this->client = $client;
$this->indexMetadataFactory = $indexMetadataFactory;
$this->documentMetadataFactory = $documentMetadataFactory;
$this->denormalizer = $denormalizer;
}

Expand All @@ -50,7 +50,7 @@ public function __construct(Client $client, DocumentMetadataFactoryInterface $in
public function supports(string $resourceClass, ?string $operationName = null, array $context = []): bool
{
try {
$this->indexMetadataFactory->create($resourceClass);
$this->documentMetadataFactory->create($resourceClass);
} catch (IndexNotFoundException $e) {
return false;
}
Expand All @@ -68,15 +68,15 @@ public function getItem(string $resourceClass, $id, ?string $operationName = nul
throw new InvalidArgumentException('Composite identifiers not supported.');
}

$id = array_values($id)[0];
$id = reset($id);
}

$indexMetadata = $this->indexMetadataFactory->create($resourceClass);
$documentMetadata = $this->documentMetadataFactory->create($resourceClass);

try {
$document = $this->client->get([
'index' => $indexMetadata->getIndex(),
'type' => $indexMetadata->getType(),
'index' => $documentMetadata->getIndex(),
'type' => $documentMetadata->getType(),
'id' => (string) $id,
]);
} catch (Missing404Exception $e) {
Expand Down
Expand Up @@ -40,35 +40,35 @@ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFa
*/
public function create(string $resourceClass): DocumentMetadata
{
$indexMetadata = null;
$documentMetadata = null;

if ($this->decorated) {
try {
$indexMetadata = $this->decorated->create($resourceClass);
$documentMetadata = $this->decorated->create($resourceClass);
} catch (IndexNotFoundException $e) {
}
}

$resourceMetadata = null;

if (!$indexMetadata || null === $indexMetadata->getIndex()) {
if (!$documentMetadata || null === $documentMetadata->getIndex()) {
$resourceMetadata = $resourceMetadata ?? $this->resourceMetadataFactory->create($resourceClass);

if (null !== $index = $resourceMetadata->getAttribute('elasticsearch_index')) {
$indexMetadata = $indexMetadata ? $indexMetadata->withIndex($index) : new DocumentMetadata($index);
$documentMetadata = $documentMetadata ? $documentMetadata->withIndex($index) : new DocumentMetadata($index);
}
}

if (!$indexMetadata || DocumentMetadata::DEFAULT_TYPE === $indexMetadata->getType()) {
if (!$documentMetadata || DocumentMetadata::DEFAULT_TYPE === $documentMetadata->getType()) {
$resourceMetadata = $resourceMetadata ?? $this->resourceMetadataFactory->create($resourceClass);

if (null !== $type = $resourceMetadata->getAttribute('elasticsearch_type')) {
$indexMetadata = $indexMetadata ? $indexMetadata->withType($type) : new DocumentMetadata(null, $type);
$documentMetadata = $documentMetadata ? $documentMetadata->withType($type) : new DocumentMetadata(null, $type);
}
}

if ($indexMetadata) {
return $indexMetadata;
if ($documentMetadata) {
return $documentMetadata;
}

throw new IndexNotFoundException(sprintf('No index associated with the "%s" resource class.', $resourceClass));
Expand Down
Expand Up @@ -58,23 +58,23 @@ public function create(string $resourceClass): DocumentMetadata
return $this->handleNotFound($this->localCache[$resourceClass] = $cacheItem->get(), $resourceClass);
}

$indexMetadata = $this->decorated->create($resourceClass);
$documentMetadata = $this->decorated->create($resourceClass);

$cacheItem->set($indexMetadata);
$cacheItem->set($documentMetadata);
$this->cacheItemPool->save($cacheItem);

return $this->handleNotFound($this->localCache[$resourceClass] = $indexMetadata, $resourceClass);
return $this->handleNotFound($this->localCache[$resourceClass] = $documentMetadata, $resourceClass);
}

/**
* @throws IndexNotFoundException
*/
private function handleNotFound(DocumentMetadata $indexMetadata, string $resourceClass): DocumentMetadata
private function handleNotFound(DocumentMetadata $documentMetadata, string $resourceClass): DocumentMetadata
{
if (null === $indexMetadata->getIndex()) {
if (null === $documentMetadata->getIndex()) {
throw new IndexNotFoundException(sprintf('No index associated with the "%s" resource class.', $resourceClass));
}

return $indexMetadata;
return $documentMetadata;
}
}
Expand Up @@ -47,33 +47,33 @@ public function __construct(Client $client, ResourceMetadataFactoryInterface $re
*/
public function create(string $resourceClass): DocumentMetadata
{
$indexMetadata = null;
$documentMetadata = null;

if ($this->decorated) {
try {
$indexMetadata = $this->decorated->create($resourceClass);
$documentMetadata = $this->decorated->create($resourceClass);
} catch (IndexNotFoundException $e) {
}
}

if ($indexMetadata && null !== $indexMetadata->getIndex()) {
return $indexMetadata;
if ($documentMetadata && null !== $documentMetadata->getIndex()) {
return $documentMetadata;
}

$index = Inflector::tableize($this->resourceMetadataFactory->create($resourceClass)->getShortName());

try {
$this->client->cat()->indices(['index' => $index]);
} catch (Missing404Exception $e) {
if ($indexMetadata) {
return $indexMetadata;
if ($documentMetadata) {
return $documentMetadata;
}

throw new IndexNotFoundException(sprintf('No index associated with the "%s" resource class.', $resourceClass));
}

if ($indexMetadata) {
return $indexMetadata->withIndex($index);
if ($documentMetadata) {
return $documentMetadata->withIndex($index);
}

return new DocumentMetadata($index);
Expand Down

0 comments on commit 0aa292b

Please sign in to comment.