Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-31783: Fixed RichTextEmbedAllowedContentTypes subscriber implementation #1539

Merged
merged 1 commit into from
Sep 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

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

namespace EzSystems\EzPlatformAdminUi\Tests\UniversalDiscovery\Event\Subscriber;

use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\PermissionResolver;
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
use eZ\Publish\API\Repository\Values\User\Limitation\ContentTypeLimitation;
use EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface;
use EzSystems\EzPlatformAdminUi\UniversalDiscovery\Event\ConfigResolveEvent;
use EzSystems\EzPlatformAdminUi\UniversalDiscovery\Event\Subscriber\RichTextEmbedAllowedContentTypes;
use PHPUnit\Framework\TestCase;

final class RichTextEmbedAllowedContentTypesTest extends TestCase
{
private const EXAMPLE_LIMITATIONS = [/* Some limitations */];

private const SUPPORTED_CONFIG_NAMES = ['richtext_embed', 'richtext_embed_image'];

private const ALLOWED_CONTENT_TYPES_IDS = [2, 4];
private const ALLOWED_CONTENT_TYPES = ['article', 'folder'];

/** @var \eZ\Publish\API\Repository\PermissionResolver|\PHPUnit\Framework\MockObject\MockObject */
private $permissionResolver;

/** @var \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface|\PHPUnit\Framework\MockObject\MockObject */
private $permissionChecker;

/** @var \eZ\Publish\API\Repository\ContentTypeService|\PHPUnit\Framework\MockObject\MockObject */
private $contentTypeService;

/** @var \EzSystems\EzPlatformAdminUi\UniversalDiscovery\Event\Subscriber\RichTextEmbedAllowedContentTypes */
private $subscriber;

protected function setUp(): void
{
$this->permissionResolver = $this->createMock(PermissionResolver::class);
$this->permissionChecker = $this->createMock(PermissionCheckerInterface::class);
$this->contentTypeService = $this->createMock(ContentTypeService::class);

$this->subscriber = new RichTextEmbedAllowedContentTypes(
$this->permissionResolver,
$this->permissionChecker,
$this->contentTypeService
);
}

public function testUdwConfigResolveOnUnsupportedConfigName(): void
{
$this->permissionResolver->expects($this->never())->method('hasAccess');
$this->permissionChecker->expects($this->never())->method('getRestrictions');
$this->contentTypeService->expects($this->never())->method('loadContentTypeList');

$event = $this->createConfigResolveEvent('unsupported_config_name');

$this->subscriber->onUdwConfigResolve($event);

$this->assertEquals([], $event->getConfig());
}

/**
* @dataProvider dataProviderForUdwConfigResolveWhenThereIsNoContentReadLimitations
*/
public function testUdwConfigResolveWhenThereIsNoContentReadLimitations(bool $hasAccess): void
{
$this->permissionResolver->method('hasAccess')->with('content', 'read')->willReturn($hasAccess);
$this->permissionChecker->expects($this->never())->method('getRestrictions');
$this->contentTypeService->expects($this->never())->method('loadContentTypeList');

$this->assertConfigurationResolvingResult([
'allowed_content_types' => null,
]);
}

public function dataProviderForUdwConfigResolveWhenThereIsNoContentReadLimitations(): iterable
{
return [
['hasAccess' => false],
['hasAccess' => true],
];
}

public function testUdwConfigResolveWhenThereAreContentReadLimitations(): void
{
$this->permissionResolver
->method('hasAccess')
->with('content', 'read')
->willReturn(self::EXAMPLE_LIMITATIONS);

$this->permissionChecker
->method('getRestrictions')
->with(self::EXAMPLE_LIMITATIONS, ContentTypeLimitation::class)
->willReturn(self::ALLOWED_CONTENT_TYPES_IDS);

$this->contentTypeService
->method('loadContentTypeList')
->with(self::ALLOWED_CONTENT_TYPES_IDS)
->willReturn($this->createContentTypeListMock(self::ALLOWED_CONTENT_TYPES));

$this->assertConfigurationResolvingResult([
'allowed_content_types' => self::ALLOWED_CONTENT_TYPES,
]);
}

private function assertConfigurationResolvingResult(?array $expectedConfiguration): void
{
foreach (self::SUPPORTED_CONFIG_NAMES as $configName) {
$event = $this->createConfigResolveEvent($configName);

$this->subscriber->onUdwConfigResolve($event);

$this->assertEquals(
$expectedConfiguration,
$event->getConfig()
);
}
}

private function createConfigResolveEvent(string $configName = 'richtext_embed'): ConfigResolveEvent
{
$event = new ConfigResolveEvent();
$event->setConfigName($configName);

return $event;
}

private function createContentTypeListMock(array $identifiers): array
{
return array_map(function (string $identifier) {
$contentType = $this->createMock(ContentType::class);
$contentType->method('__get')->with('identifier')->willReturn($identifier);

return $contentType;
}, $identifiers);
}
}
6 changes: 3 additions & 3 deletions src/lib/UniversalDiscovery/Event/ConfigResolveEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@

class ConfigResolveEvent extends Event
{
const NAME = 'udw.resolve.config';
public const NAME = 'udw.resolve.config';

/** @var string */
protected $configName;

/** @var array */
protected $config;
protected $config = [];

/** @var array */
protected $context;
protected $context = [];

/**
* @return string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,84 +10,67 @@

use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\PermissionResolver;
use eZ\Publish\API\Repository\Values\ContentType\ContentType;
use eZ\Publish\API\Repository\Values\User\Limitation\ContentTypeLimitation;
use EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface;
use EzSystems\EzPlatformAdminUi\UniversalDiscovery\Event\ConfigResolveEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RichTextEmbedAllowedContentTypes implements EventSubscriberInterface
final class RichTextEmbedAllowedContentTypes implements EventSubscriberInterface
{
/** @var string[] */
private $allowedContentTypesIdentifiers;
/** @var \eZ\Publish\API\Repository\PermissionResolver */
private $permissionResolver;

/** @var \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface */
private $permissionChecker;

/** @var \eZ\Publish\API\Repository\ContentTypeService */
private $contentTypeService;

/** @var string[]|null */
private $allowedContentTypesIdentifiers = null;

/**
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
* @param \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface $permissionChecker
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
public function __construct(
PermissionResolver $permissionResolver,
PermissionCheckerInterface $permissionChecker,
ContentTypeService $contentTypeService
) {
$this->allowedContentTypesIdentifiers = $this->getAllowedContentTypesIdentifiers(
$permissionResolver,
$permissionChecker,
$contentTypeService
);
$this->permissionResolver = $permissionResolver;
$this->permissionChecker = $permissionChecker;
$this->contentTypeService = $contentTypeService;
}

/**
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
* @param \EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface $permissionChecker
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
private function getAllowedContentTypesIdentifiers(
PermissionResolver $permissionResolver,
PermissionCheckerInterface $permissionChecker,
ContentTypeService $contentTypeService
): array {
$access = $permissionResolver->hasAccess('content', 'read');
private function getAllowedContentTypesIdentifiers(): array
{
$access = $this->permissionResolver->hasAccess('content', 'read');
if (!\is_array($access)) {
return [];
}

$restrictedContentTypesIds = $permissionChecker->getRestrictions($access, ContentTypeLimitation::class);

$restrictedContentTypesIds = $this->permissionChecker->getRestrictions($access, ContentTypeLimitation::class);
if (empty($restrictedContentTypesIds)) {
return [];
}

$restrictedContentTypes = $contentTypeService->loadContentTypeList($restrictedContentTypesIds);
$allowedContentTypesIdentifiers = [];

$restrictedContentTypes = $this->contentTypeService->loadContentTypeList($restrictedContentTypesIds);
foreach ($restrictedContentTypes as $contentType) {
$allowedContentTypesIdentifiers[] = $contentType->identifier;
}

return array_values(
array_map(
static function (ContentType $contentType): string {
return $contentType->identifier;
},
iterator_to_array($restrictedContentTypes)
)
);
return $allowedContentTypesIdentifiers;
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
ConfigResolveEvent::NAME => ['onUdwConfigResolve', -10],
];
}

/**
* @param \EzSystems\EzPlatformAdminUi\UniversalDiscovery\Event\ConfigResolveEvent $event
*/
public function onUdwConfigResolve(ConfigResolveEvent $event): void
{
$config = $event->getConfig();
Expand All @@ -96,7 +79,11 @@ public function onUdwConfigResolve(ConfigResolveEvent $event): void
return;
}

$config['allowed_content_types'] = !empty($this->allowedContentTypesIdentifiers) ? $this->restrictedContentTypesIdentifier : null;
if ($this->allowedContentTypesIdentifiers === null) {
$this->allowedContentTypesIdentifiers = $this->getAllowedContentTypesIdentifiers();
}

$config['allowed_content_types'] = !empty($this->allowedContentTypesIdentifiers) ? $this->allowedContentTypesIdentifiers : null;

$event->setConfig($config);
}
Expand Down