Skip to content

Commit

Permalink
Merge pull request #90 from ezsystems/ezp32182-enhanced_location_hand…
Browse files Browse the repository at this point in the history
…ling

Enhanced location handling (EZP-32182)
  • Loading branch information
Bertrand Dunogier authored Dec 10, 2020
2 parents c1d285e + 40a8a42 commit e12b757
Show file tree
Hide file tree
Showing 65 changed files with 1,886 additions and 164 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.3.x-dev"
"dev-master": "3.0.x-dev"
}
},
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@

namespace spec\EzSystems\EzPlatformGraphQL\GraphQL\InputMapper;

use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Subtree;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\ContentCollectionFilterBuilder;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper;
use eZ\Publish\API\Repository\Values\Content\Query;
use PhpSpec\ObjectBehavior;

class SearchQueryMapperSpec extends ObjectBehavior
{
function let(ContentCollectionFilterBuilder $filterBuilder)
{
$this->beConstructedWith($filterBuilder);

$filterBuilder->buildFilter()->willReturn(new SubTree('/1/2/'));
}

function it_is_initializable()
{
$this->shouldHaveType(SearchQueryMapper::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use eZ\Publish\API\Repository\Values\Content\Query;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\DataLoader\ContentTypeLoader;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\QueryMapper;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\DomainContentResolver;
use eZ\Publish\API\Repository\Repository;
use eZ\Publish\Core\FieldType;
Expand All @@ -24,7 +24,7 @@ class DomainContentResolverSpec extends ObjectBehavior
function let(
Repository $repository,
TypeResolver $typeResolver,
SearchQueryMapper $queryMapper,
QueryMapper $queryMapper,
ContentLoader $contentLoader,
ContentTypeLoader $contentTypeLoader
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace spec\EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser;

use eZ\Publish\Core\Repository\Values\Content\Content;
use eZ\Publish\Core\Repository\Values\Content\Location;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\FilterLocationGuesser;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationFilter;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationGuess;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationGuesser;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\ObjectStorageLocationList;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationList;
use EzSystems\EzPlatformGraphQL\GraphQL\Resolver\LocationGuesser\LocationProvider;
use PhpSpec\ObjectBehavior;

class FilterLocationGuesserSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(FilterLocationGuesser::class);
$this->shouldHaveType(LocationGuesser::class);
}

function let(LocationProvider $locationProvider, LocationFilter $locationFilter, LocationFilter $otherLocationFilter)
{
$this->beConstructedWith($locationProvider, [$locationFilter, $otherLocationFilter]);
}

function it_gets_the_initial_location_list_from_the_provider(LocationProvider $locationProvider)
{
$content = new Content();
$locationProvider->getLocations($content)->willReturn(new ObjectStorageLocationList($content));
$this->guessLocation($content);
}

function it_does_not_filter_if_there_is_only_one_location(LocationProvider $locationProvider, LocationFilter $locationFilter)
{
$content = new Content();
$location = new Location();
$locationList = new ObjectStorageLocationList($content);
$locationList->addLocation($location);

$locationProvider->getLocations($content)->willReturn($locationList);

$locationFilter->filter($content, $locationList)->shouldNotBeCalled();
$this->guessLocation($content)->shouldBeLike(new LocationGuess($content, [$location]));
}

function it_returns_as_soon_as_there_is_one_location_left(
LocationProvider $locationProvider,
LocationFilter $locationFilter,
LocationFilter $secondLocationFilter,
LocationList $locationList
)
{
$content = new Content();
$firstLocation = new Location();
$secondLocation = new Location();

$locationProvider->getLocations($content)->willReturn($locationList);
$locationList->hasOneLocation()->willReturn(false);
$locationList->getLocations()->willReturn([$firstLocation]);
$locationFilter->filter($content, $locationList)->will(function ($args) use ($locationList) {
$locationList->hasOneLocation()->willReturn(true);
});

$secondLocationFilter->filter($content, $locationList)->shouldNotBeCalled();

$this->guessLocation($content)->shouldGuess($firstLocation);
}

public function getMatchers(): array
{
return [
'guess' => function (LocationGuess $subject, Location $location) {
return $subject->isSuccessful() && $subject->getLocation() === $location;
}
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ function let(NameHelper $nameHelper, ContentTypeService $contentTypeService, Fie
$contentTypeService->loadContentTypeByIdentifier('article')->willReturn($articleContentType);
$contentTypeService->loadContentTypeByIdentifier('folder')->willReturn($folderContentType);

$nameHelper->domainContentName($articleContentType)->willReturn('ArticleContent');
$nameHelper->domainContentName($folderContentType)->willReturn('FolderContent');
$nameHelper->itemName($articleContentType)->willReturn('ArticleItem');
$nameHelper->itemName($folderContentType)->willReturn('FolderItem');
}

function it_is_initializable()
Expand All @@ -38,37 +38,37 @@ function it_is_initializable()
function it_maps_single_selection_without_type_limitations_to_a_single_generic_content()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_SINGLE, []);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('DomainContent');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('Item');
}

function it_maps_single_selection_with_multiple_type_limitations_to_a_single_generic_content()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_SINGLE, ['article', 'blog_post']);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('DomainContent');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('Item');
}

function it_maps_single_selection_with_a_unique_type_limitations_to_a_single_item_of_that_type()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_SINGLE, ['article']);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('ArticleContent');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('ArticleItem');
}

function it_maps_multi_selection_without_type_limitations_to_an_array_of_generic_content()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_MULTI, []);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[DomainContent]');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[Item]');
}

function it_maps_multi_selection_with_multiple_type_limitations_to_an_array_of_generic_content()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_NONE, ['article', 'blog_post']);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[DomainContent]');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[Item]');
}

function it_maps_multi_selection_with_a_unique_type_limitations_to_an_array_of_that_type()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_MULTI, ['article']);
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[ArticleContent]');
$this->mapToFieldValueType($fieldDefinition)->shouldReturn('[ArticleItem]');
}

function it_delegates_the_field_definition_type_to_the_inner_mapper(FieldDefinitionMapper $innerMapper)
Expand All @@ -81,13 +81,13 @@ function it_delegates_the_field_definition_type_to_the_inner_mapper(FieldDefinit
function it_maps_multi_selection_to_resolve_multiple()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_MULTI);
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("DomainRelationFieldValue", [field, true])');
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("RelationFieldValue", [field, true])');
}

function it_maps_singl_selection_to_resolve_single()
function it_maps_single_selection_to_resolve_single()
{
$fieldDefinition = $this->createFieldDefinition(self::DEF_LIMIT_SINGLE);
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("DomainRelationFieldValue", [field, false])');
$this->mapToFieldValueResolver($fieldDefinition)->shouldReturn('@=resolver("RelationFieldValue", [field, false])');
}

private function createFieldDefinition($selectionLimit = 0, $selectionContentTypes = [])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ function it_is_initializable()
function it_removes_special_characters_from_ContentTypeGroup_identifier()
{
$contentTypeGroup = new ContentTypeGroup(['identifier' => 'Name with-hyphen']);
$this->domainGroupName($contentTypeGroup)->shouldBe('DomainGroupNameWithHyphen');
$this->itemGroupName($contentTypeGroup)->shouldBe('ItemGroupNameWithHyphen');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,40 @@

use EzSystems\EzPlatformGraphQL\Schema\Builder\SchemaBuilder;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\NameHelper;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddContentOfTypeConnectionToDomainGroup;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddDomainContentCollectionToDomainGroup;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddItemOfTypeConnectionToGroup;
use spec\EzSystems\EzPlatformGraphQL\Tools\ContentTypeArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\ContentTypeGroupArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\FieldArgArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\FieldArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\TypeArgument;
use Prophecy\Argument;

class AddContentOfTypeConnectionToDomainGroupSpec extends ContentTypeWorkerBehavior
class AddItemOfTypeConnectionToGroupSpec extends ContentTypeWorkerBehavior
{
const GROUP_TYPE = 'DomainGroupTestGroup';
const TYPE_TYPE = 'TestTypeContentConnection';
const COLLECTION_FIELD = 'testTypes';
const GROUP_TYPE = 'ItemTestGroup';
const TYPE_TYPE = 'TestItemConnection';
const CONNECTION_FIELD = 'testTypes';

function let(NameHelper $nameHelper)
{
$this->setNameHelper($nameHelper);

$nameHelper
->domainGroupName(ContentTypeGroupArgument::withIdentifier(self::GROUP_IDENTIFIER))
->itemGroupName(ContentTypeGroupArgument::withIdentifier(self::GROUP_IDENTIFIER))
->willReturn(self::GROUP_TYPE);

$nameHelper
->domainContentCollectionField(ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER))
->willReturn(self::COLLECTION_FIELD);
->itemConnectionField(ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER))
->willReturn(self::CONNECTION_FIELD);

$nameHelper
->domainContentConnection(ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER))
->itemConnectionName(ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER))
->willReturn(self::TYPE_TYPE);
}

function it_is_initializable()
{
$this->shouldHaveType(AddContentOfTypeConnectionToDomainGroup::class);
$this->shouldHaveType(AddItemOfTypeConnectionToGroup::class);
}

function it_can_not_work_if_args_do_not_include_a_ContentTypeGroup(SchemaBuilder $schema)
Expand All @@ -55,7 +54,7 @@ function it_can_not_work_if_args_do_not_include_a_ContentType(SchemaBuilder $sch

function it_can_not_work_if_the_collection_field_is_already_set(SchemaBuilder $schema)
{
$schema->hasTypeWithField(self::GROUP_TYPE, self::COLLECTION_FIELD)->willReturn(true);
$schema->hasTypeWithField(self::GROUP_TYPE, self::CONNECTION_FIELD)->willReturn(true);
$this->canWork($schema, $this->args())->shouldBe(false);
}

Expand All @@ -65,18 +64,18 @@ function it_adds_a_collection_field_for_the_ContentType_to_the_ContentTypeGroup(
->addFieldToType(
self::GROUP_TYPE,
Argument::allOf(
FieldArgument::hasName(self::COLLECTION_FIELD),
FieldArgument::hasName(self::CONNECTION_FIELD),
FieldArgument::hasType(self::TYPE_TYPE),
FieldArgument::hasDescription(self::TYPE_DESCRIPTION),
FieldArgument::withResolver('SearchContentOfTypeAsConnection')
FieldArgument::withResolver('ItemsOfTypeAsConnection')
)
)
->shouldBeCalled();

$schema
->addArgToField(
self::GROUP_TYPE,
self::COLLECTION_FIELD,
self::CONNECTION_FIELD,
Argument::allOf(
FieldArgArgument::withName('query'),
FieldArgArgument::withType('ContentSearchQuery')
Expand All @@ -87,7 +86,7 @@ function it_adds_a_collection_field_for_the_ContentType_to_the_ContentTypeGroup(
$schema
->addArgToField(
self::GROUP_TYPE,
self::COLLECTION_FIELD,
self::CONNECTION_FIELD,
Argument::allOf(
FieldArgArgument::withName('sortBy'),
FieldArgArgument::withType('[SortByOptions]')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace spec\EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType;

use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddDomainContentToDomainGroup;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddItemToGroup;

class AddDomainContentToDomainGroupSpec extends ContentTypeWorkerBehavior
class AddItemToGroupSpec extends ContentTypeWorkerBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(AddDomainContentToDomainGroup::class);
$this->shouldHaveType(AddItemToGroup::class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,45 @@

use EzSystems\EzPlatformGraphQL\Schema\Builder\SchemaBuilder;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\NameHelper;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddContentTypeToDomainGroupTypes;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddItemTypeToItemGroupTypes;
use spec\EzSystems\EzPlatformGraphQL\Tools\ContentTypeArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\ContentTypeGroupArgument;
use spec\EzSystems\EzPlatformGraphQL\Tools\FieldArgument;
use Prophecy\Argument;

class AddContentTypeToDomainGroupTypesSpec extends ContentTypeWorkerBehavior
class AddItemTypeToItemGroupTypesSpec extends ContentTypeWorkerBehavior
{
const GROUP_TYPES_TYPE = 'DomainGroupTestGroupTypes';

const TYPE_FIELD = 'testType';
const TYPE_TYPE = 'TestTypeContentType';
const TYPE_TYPE = 'TestTypeType';

public function let(NameHelper $nameHelper)
{
$this->setNameHelper($nameHelper);

$nameHelper
->domainContentField(
->itemField(
ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER)
)
->willReturn(self::TYPE_FIELD);

$nameHelper
->domainContentTypeName(
->itemTypeName(
ContentTypeArgument::withIdentifier(self::TYPE_IDENTIFIER)
)
->willReturn(self::TYPE_TYPE);

$nameHelper
->domainGroupTypesName(
->itemGroupTypesName(
ContentTypeGroupArgument::withIdentifier(self::GROUP_IDENTIFIER)
)
->willReturn(self::GROUP_TYPES_TYPE);
}

function it_is_initializable()
{
$this->shouldHaveType(AddContentTypeToDomainGroupTypes::class);
$this->shouldHaveType(AddItemTypeToItemGroupTypes::class);
}

function it_can_not_work_if_args_do_not_have_a_ContentTypeGroup(SchemaBuilder $schema)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

use EzSystems\EzPlatformGraphQL\Schema\Builder\SchemaBuilder;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\NameHelper;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddContentTypeToContentTypeIdentifierList;
use EzSystems\EzPlatformGraphQL\Schema\Domain\Content\Worker\ContentType\AddItemTypeToItemTypeIdentifierList;
use spec\EzSystems\EzPlatformGraphQL\Tools\EnumValueArgument;
use Prophecy\Argument;

class AddContentTypeToContentTypeIdentifierListSpec extends ContentTypeWorkerBehavior
class AddItemTypeToItemTypeIdentifierListSpec extends ContentTypeWorkerBehavior
{
const ENUM_TYPE = 'ContentTypeIdentifier';

Expand All @@ -19,7 +19,7 @@ public function let(NameHelper $nameHelper)

function it_is_initializable()
{
$this->shouldHaveType(AddContentTypeToContentTypeIdentifierList::class);
$this->shouldHaveType(AddItemTypeToItemTypeIdentifierList::class);
}

function it_can_not_work_if_args_do_not_have_a_ContentType(SchemaBuilder $schema)
Expand Down
Loading

0 comments on commit e12b757

Please sign in to comment.