Skip to content

Commit

Permalink
Merge remote-tracking branch 'ezpublish-kernel/7.5' into 1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
barw4 committed Jul 29, 2020
2 parents a7335a4 + 08bd2de commit 5e9f57f
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 0 deletions.
25 changes: 25 additions & 0 deletions eZ/Publish/Core/Repository/LocationResolver/LocationResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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 eZ\Publish\Core\Repository\LocationResolver;

use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\API\Repository\Values\Content\Location;

/**
* @internal For internal use by eZ Platform core packages
*/
interface LocationResolver
{
/**
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
*/
public function resolveLocation(ContentInfo $contentInfo): Location;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?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 eZ\Publish\Core\Repository\LocationResolver;

use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\Core\Base\Exceptions\NotFoundException as CoreNotFoundException;

/**
* @internal For internal use by eZ Platform core packages
*/
final class PermissionAwareLocationResolver implements LocationResolver
{
/** @var \eZ\Publish\API\Repository\LocationService */
private $locationService;

public function __construct(LocationService $locationService)
{
$this->locationService = $locationService;
}

/**
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
*/
public function resolveLocation(ContentInfo $contentInfo): Location
{
try {
if (null === $contentInfo->mainLocationId) {
throw new CoreNotFoundException('location', $contentInfo->mainLocationId);
}

$location = $this->locationService->loadLocation($contentInfo->mainLocationId);
} catch (NotFoundException | UnauthorizedException $e) {
// try different locations if main location is not accessible for the user
$locations = $this->locationService->loadLocations($contentInfo);
if (empty($locations)) {
throw $e;
}

// foreach to keep forward compatibility with a type of returned loadLocations() result
foreach ($locations as $location) {
return $location;
}
}

return $location;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?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 eZ\Publish\Core\Repository\Tests\LocationResolver;

use eZ\Publish\API\Repository\Exceptions\BadStateException;
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver;
use eZ\Publish\Core\Repository\Values\Content\Location;
use PHPUnit\Framework\TestCase;

final class PermissionAwareLocationResolverTest extends TestCase
{
/** @var \eZ\Publish\API\Repository\LocationService */
private $locationService;

/** @var \eZ\Publish\Core\Repository\LocationResolver\LocationResolver */
private $locationResolver;

public function setUp(): void
{
$this->locationService = $this->createMock(LocationService::class);

$this->locationResolver = new PermissionAwareLocationResolver($this->locationService);
}

/**
* Test for the resolveLocation() method.
*
* @covers \eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver::resolveLocation
*/
public function testResolveMainLocation(): void
{
$contentInfo = new ContentInfo(['mainLocationId' => 42]);
$location = new Location(['id' => 42]);

// User has access to the main Location
$this->locationService
->method('loadLocation')
->willReturn($location);

$this->assertSame($location, $this->locationResolver->resolveLocation($contentInfo));
}

/**
* Test for the resolveLocation() method.
*
* @covers \eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver::resolveLocation
*/
public function testResolveSecondaryLocation(): void
{
$contentInfo = new ContentInfo(['mainLocationId' => 42]);
$location1 = new Location(['id' => 43]);
$location2 = new Location(['id' => 44]);

// User doesn't have access to main location but to the third Content's location
$this->locationService
->method('loadLocation')
->willThrowException($this->createMock(UnauthorizedException::class));

$this->locationService
->method('loadLocations')
->willReturn([$location1, $location2]);

$this->assertSame($location1, $this->locationResolver->resolveLocation($contentInfo));
}

/**
* Test for the resolveLocation() method when Locations don't exist.
*
* @covers \eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver::resolveLocation
*/
public function testExpectNotFoundExceptionWhenLocationDoesNotExist(): void
{
$contentInfo = new ContentInfo(['mainLocationId' => 42]);

$this->locationService
->method('loadLocation')
->willThrowException($this->createMock(NotFoundException::class));

$this->locationService
->method('loadLocations')
->willReturn([]);

$this->expectException(NotFoundException::class);

$this->locationResolver->resolveLocation($contentInfo);
}

/**
* Test for the resolveLocation() method when ContentInfo's mainLocationId is null.
*
* @covers \eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver::resolveLocation
*/
public function testExpectNotFoundExceptionWhenMainLocationIdIsNull(): void
{
$contentInfo = new ContentInfo(['mainLocationId' => null]);

$this->expectException(NotFoundException::class);

$this->locationResolver->resolveLocation($contentInfo);
}

/**
* Test for the resolveLocation() method when Location is not yet published.
*
* @covers \eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver::resolveLocation
*/
public function testExpectBadStateExceptionWhenContentNotYetPublished(): void
{
$contentInfo = new ContentInfo(['mainLocationId' => 42, 'status' => ContentInfo::STATUS_DRAFT]);

$this->locationService
->method('loadLocation')
->willThrowException($this->createMock(NotFoundException::class));

$this->locationService
->method('loadLocations')
->willThrowException($this->createMock(BadStateException::class));

$this->expectException(BadStateException::class);

$this->locationResolver->resolveLocation($contentInfo);
}
}
8 changes: 8 additions & 0 deletions eZ/Publish/Core/settings/repository/inner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,11 @@ services:
- ezplatform.spi.content.validator

eZ\Publish\SPI\Repository\Validator\ContentValidator: '@eZ\Publish\Core\Repository\Strategy\ContentValidator\ContentValidatorStrategy'

# LocationResolver
eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver:
arguments:
- '@ezpublish.api.service.location'

eZ\Publish\Core\Repository\LocationResolver\LocationResolver:
alias: eZ\Publish\Core\Repository\LocationResolver\PermissionAwareLocationResolver

0 comments on commit 5e9f57f

Please sign in to comment.