Skip to content

Commit 80a7dc1

Browse files
committed
Added tests for IBX-10854: Not possible to hide content draft
1 parent 9d5ac6d commit 80a7dc1

3 files changed

Lines changed: 237 additions & 49 deletions

File tree

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33768,11 +33768,6 @@ parameters:
3376833768
count: 4
3376933769
path: tests/integration/Core/Repository/ContentServiceTest.php
3377033770

33771-
-
33772-
message: '#^Parameter \#1 \$locationId of method Ibexa\\Contracts\\Core\\Repository\\LocationService\:\:loadLocation\(\) expects int, int\|null given\.$#'
33773-
identifier: argument.type
33774-
count: 12
33775-
path: tests/integration/Core/Repository/ContentServiceTest.php
3377633771

3377733772
-
3377833773
message: '#^Parameter \#1 \$locations of method Ibexa\\Tests\\Integration\\Core\\Repository\\ContentServiceTest\:\:filterHiddenLocations\(\) expects array\<Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\>, iterable\<Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\> given\.$#'

src/lib/Repository/ContentService.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,17 +2531,17 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $
25312531
*/
25322532
public function hideContent(ContentInfo $contentInfo): void
25332533
{
2534-
// If content is in draft state, mainLocationId is yet not set
2535-
if ($contentInfo->mainLocationId !== null) {
2536-
$locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo));
2537-
if (!$this->permissionResolver->canUser(
2538-
'content',
2539-
'hide',
2540-
$contentInfo,
2541-
[$locationTarget]
2542-
)) {
2543-
throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]);
2544-
}
2534+
// If ContentInfo is in draft state, mainLocationId is yet not set
2535+
$targets = $contentInfo->isDraft()
2536+
? []
2537+
: [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)];
2538+
if (!$this->permissionResolver->canUser(
2539+
'content',
2540+
'hide',
2541+
$contentInfo,
2542+
$targets
2543+
)) {
2544+
throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]);
25452545
}
25462546

25472547
$this->repository->beginTransaction();
@@ -2574,17 +2574,18 @@ public function hideContent(ContentInfo $contentInfo): void
25742574
*/
25752575
public function revealContent(ContentInfo $contentInfo): void
25762576
{
2577-
// If content is in draft state, mainLocationId is yet not set
2578-
if ($contentInfo->mainLocationId !== null) {
2579-
$locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo));
2580-
if (!$this->permissionResolver->canUser(
2581-
'content',
2582-
'hide',
2583-
$contentInfo,
2584-
[$locationTarget]
2585-
)) {
2586-
throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]);
2587-
}
2577+
// If ContentInfo is in draft state, mainLocationId is yet not set
2578+
$targets = $contentInfo->isDraft()
2579+
? []
2580+
: [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)];
2581+
2582+
if (!$this->permissionResolver->canUser(
2583+
'content',
2584+
'hide',
2585+
$contentInfo,
2586+
$targets
2587+
)) {
2588+
throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]);
25882589
}
25892590

25902591
$this->repository->beginTransaction();

tests/integration/Core/Repository/ContentServiceTest.php

Lines changed: 214 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3610,7 +3610,9 @@ public function testLoadRelationsSkipsArchivedContent()
36103610
$demoDesign
36113611
);
36123612

3613-
$demoDesignLocation = $this->locationService->loadLocation($demoDesign->mainLocationId);
3613+
$demoDesignMainLocationId = $demoDesign->getMainLocationId();
3614+
self::assertNotNull($demoDesignMainLocationId, 'Expected mainLocationId to be set for this test case.');
3615+
$demoDesignLocation = $this->locationService->loadLocation($demoDesignMainLocationId);
36143616

36153617
// Trashing Content's last Location will change its status to archived,
36163618
// in this case relation towards it will not be loaded.
@@ -3936,7 +3938,9 @@ public function testLoadReverseRelationsSkipsArchivedContent()
39363938
$this->contentService->publishVersion($mediaDraft->getVersionInfo());
39373939
$this->contentService->publishVersion($demoDesignDraft->getVersionInfo());
39383940

3939-
$demoDesignLocation = $this->locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId);
3941+
$demoDesignLocationId = $demoDesignDraft->getContentInfo()->getMainLocationId();
3942+
self::assertNotNull($demoDesignLocationId, 'Expected mainLocationId to be set for this test case.');
3943+
$demoDesignLocation = $this->locationService->loadLocation($demoDesignLocationId);
39403944

39413945
// Trashing Content's last Location will change its status to archived,
39423946
// in this case relation from it will not be loaded.
@@ -4138,7 +4142,9 @@ public function testLoadReverseRelationListSkipsArchivedContent(): void
41384142
$draft3,
41394143
]);
41404144

4141-
$locationToTrash = $this->locationService->loadLocation($draft3->contentInfo->mainLocationId);
4145+
$draft3MainLocationId = $draft3->getContentInfo()->getMainLocationId();
4146+
self::assertNotNull($draft3MainLocationId, 'Expected mainLocationId to be set for this test case.');
4147+
$locationToTrash = $this->locationService->loadLocation($draft3MainLocationId);
41424148

41434149
// Trashing Content's last Location will change its status to archived, in this case relation from it will not be loaded.
41444150
$trashService->trash($locationToTrash);
@@ -5100,9 +5106,9 @@ public function testURLAliasesCreatedForNewContent()
51005106
// Automatically creates a new URLAlias for the content
51015107
$liveContent = $this->contentService->publishVersion($draft->getVersionInfo());
51025108

5103-
$location = $this->locationService->loadLocation(
5104-
$liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5105-
);
5109+
$liveContentInfoMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId();
5110+
self::assertNotNull($liveContentInfoMainLocationId, 'Expected mainLocationId to be set for this test case.');
5111+
$location = $this->locationService->loadLocation($liveContentInfoMainLocationId);
51065112

51075113
$aliases = $urlAliasService->listLocationAliases($location, false);
51085114

@@ -5128,9 +5134,9 @@ public function testURLAliasesCreatedForUpdatedContent()
51285134

51295135
$draft = $this->createUpdatedDraftVersion2();
51305136

5131-
$location = $this->locationService->loadLocation(
5132-
$draft->getVersionInfo()->getContentInfo()->mainLocationId
5133-
);
5137+
$draftMainLocationId = $draft->getVersionInfo()->getContentInfo()->getMainLocationId();
5138+
self::assertNotNull($draftMainLocationId, 'Expected mainLocationId to be set for this test case.');
5139+
$location = $this->locationService->loadLocation($draftMainLocationId);
51345140

51355141
// Load and assert URL aliases before publishing updated Content, so that
51365142
// SPI cache is warmed up and cache invalidation is also tested.
@@ -5156,9 +5162,9 @@ public function testURLAliasesCreatedForUpdatedContent()
51565162
// and creates new aliases, based on the changes
51575163
$liveContent = $this->contentService->publishVersion($draft->getVersionInfo());
51585164

5159-
$location = $this->locationService->loadLocation(
5160-
$liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5161-
);
5165+
$liveContentInfoMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId();
5166+
self::assertNotNull($liveContentInfoMainLocationId, 'Expected mainLocationId to be set for this test case.');
5167+
$location = $this->locationService->loadLocation($liveContentInfoMainLocationId);
51625168

51635169
$aliases = $urlAliasService->listLocationAliases($location, false);
51645170

@@ -5195,11 +5201,11 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
51955201

51965202
$content = $this->createContentVersion1();
51975203

5204+
$contentMainLocationId = $content->getVersionInfo()->getContentInfo()->getMainLocationId();
5205+
self::assertNotNull($contentMainLocationId, 'Expected mainLocationId to be set for this test case.');
51985206
// Create a custom URL alias
51995207
$urlAliasService->createUrlAlias(
5200-
$this->locationService->loadLocation(
5201-
$content->getVersionInfo()->getContentInfo()->mainLocationId
5202-
),
5208+
$this->locationService->loadLocation($contentMainLocationId),
52035209
'/my/fancy/story-about-ibexa-dxp',
52045210
self::ENG_US
52055211
);
@@ -5219,9 +5225,9 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
52195225
// the custom one is left untouched
52205226
$liveContent = $this->contentService->publishVersion($draftVersion2->getVersionInfo());
52215227

5222-
$location = $this->locationService->loadLocation(
5223-
$liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5224-
);
5228+
$liveContentMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId();
5229+
self::assertNotNull($liveContentMainLocationId, 'Expected mainLocationId to be set for this test case.');
5230+
$location = $this->locationService->loadLocation($liveContentMainLocationId);
52255231

52265232
$aliases = $urlAliasService->listLocationAliases($location);
52275233

@@ -5391,7 +5397,12 @@ public function testDeleteTranslationUpdatesUrlAlias()
53915397
$urlAliasService = $this->getRepository()->getURLAliasService();
53925398

53935399
$content = $this->createContentVersion2();
5394-
$mainLocation = $this->locationService->loadLocation($content->contentInfo->mainLocationId);
5400+
$contentMainLocationId = $content->getContentInfo()->getMainLocationId();
5401+
self::assertNotNull(
5402+
$contentMainLocationId,
5403+
'Expected mainLocationId to be set for this test case.'
5404+
);
5405+
$mainLocation = $this->locationService->loadLocation($contentMainLocationId);
53955406

53965407
// create custom URL alias for Content main Location
53975408
$urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', self::ENG_GB);
@@ -6229,6 +6240,171 @@ function (Location $parentLocation) {
62296240
$this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal);
62306241
}
62316242

6243+
/**
6244+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
6245+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
6246+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
6247+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
6248+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
6249+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
6250+
*/
6251+
public function testPublishHiddenDraft(): void
6252+
{
6253+
$draft = $this->createFolderDraft();
6254+
$draftContentInfo = $draft->getContentInfo();
6255+
$this->contentService->hideContent($draftContentInfo);
6256+
6257+
$publishedContent = $this->contentService->publishVersion($draft->getVersionInfo());
6258+
$contentInfo = $publishedContent->getContentInfo();
6259+
6260+
self::assertTrue($contentInfo->isHidden(), 'Content is not hidden');
6261+
6262+
$mainLocationId = $contentInfo->getMainLocationId();
6263+
6264+
self::assertNotNull(
6265+
$mainLocationId,
6266+
'Expected mainLocationId to be set for this test case.'
6267+
);
6268+
6269+
$location = $this->locationService->loadLocation($mainLocationId);
6270+
self::assertTrue($location->isHidden(), 'Location is visible');
6271+
}
6272+
6273+
/**
6274+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
6275+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
6276+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
6277+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
6278+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
6279+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
6280+
*/
6281+
public function testPublishRevealedDraft(): void
6282+
{
6283+
$draft = $this->createFolderDraft();
6284+
$draftContentInfo = $draft->getContentInfo();
6285+
6286+
$this->contentService->hideContent($draftContentInfo);
6287+
self::assertTrue(
6288+
$this->contentService
6289+
->loadContent($draftContentInfo->getId())
6290+
->getContentInfo()
6291+
->isHidden()
6292+
);
6293+
6294+
$this->contentService->revealContent($draftContentInfo);
6295+
self::assertFalse(
6296+
$this->contentService
6297+
->loadContent($draftContentInfo->getId())
6298+
->getContentInfo()
6299+
->isHidden()
6300+
);
6301+
6302+
$publishedContent = $this->contentService->publishVersion(
6303+
$draft->getVersionInfo()
6304+
);
6305+
6306+
$contentInfo = $publishedContent->getContentInfo();
6307+
$mainLocationId = $contentInfo->getMainLocationId();
6308+
6309+
self::assertFalse($contentInfo->isHidden(), 'Content is hidden');
6310+
self::assertNotNull(
6311+
$mainLocationId,
6312+
'Expected mainLocationId to be set for this test case.'
6313+
);
6314+
6315+
$location = $this->locationService->loadLocation($mainLocationId);
6316+
6317+
self::assertFalse($location->isHidden(), 'Location is hidden');
6318+
}
6319+
6320+
/**
6321+
* @dataProvider draftVisibilityTransitionsProvider
6322+
*
6323+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
6324+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
6325+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
6326+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
6327+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
6328+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
6329+
*/
6330+
public function testDraftVisibilityTransitions(
6331+
bool $initiallyHidden,
6332+
bool $secondDraftHidden
6333+
): void {
6334+
$draft = $this->createFolderDraft();
6335+
6336+
if ($initiallyHidden) {
6337+
$this->contentService->hideContent($draft->getContentInfo());
6338+
}
6339+
6340+
$publishedContent = $this->contentService->publishVersion($draft->getVersionInfo());
6341+
$draft2 = $this->contentService->createContentDraft($publishedContent->getContentInfo());
6342+
6343+
if ($secondDraftHidden) {
6344+
$this->contentService->hideContent($draft2->getContentInfo());
6345+
} else {
6346+
$this->contentService->revealContent($draft2->getContentInfo());
6347+
}
6348+
6349+
$publishedContent2 = $this->contentService->publishVersion($draft2->getVersionInfo());
6350+
$contentInfo = $publishedContent2->getContentInfo();
6351+
6352+
self::assertSame(
6353+
$secondDraftHidden,
6354+
$contentInfo->isHidden(),
6355+
'Unexpected final hidden state for content.'
6356+
);
6357+
6358+
$mainLocationId = $contentInfo->getMainLocationId();
6359+
6360+
self::assertNotNull(
6361+
$mainLocationId,
6362+
'Expected mainLocationId to be set.'
6363+
);
6364+
6365+
$location = $this->locationService->loadLocation($mainLocationId);
6366+
6367+
self::assertSame(
6368+
$secondDraftHidden,
6369+
$location->isHidden(),
6370+
'Unexpected final hidden state for location.'
6371+
);
6372+
}
6373+
6374+
/**
6375+
* @return iterable<string, array{bool, bool}>
6376+
*/
6377+
public static function draftVisibilityTransitionsProvider(): iterable
6378+
{
6379+
yield 'hidden -> hidden' => [true, true];
6380+
yield 'hidden -> visible' => [true, false];
6381+
yield 'visible -> hidden' => [false, true];
6382+
yield 'visible -> visible' => [false, false];
6383+
}
6384+
6385+
/**
6386+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
6387+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
6388+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
6389+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
6390+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
6391+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
6392+
*/
6393+
private function createFolderDraft(): Content
6394+
{
6395+
$contentTypeService = $this->getRepository()->getContentTypeService();
6396+
$locationCreateStructs = $this->locationService->newLocationCreateStruct(2);
6397+
$contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6398+
6399+
$contentCreate = $this->contentService->newContentCreateStruct($contentType, self::ENG_US);
6400+
$contentCreate->setField('name', 'Folder to hide');
6401+
6402+
return $this->contentService->createContent(
6403+
$contentCreate,
6404+
[$locationCreateStructs]
6405+
);
6406+
}
6407+
62326408
/**
62336409
* @depends testRevealContent
62346410
*/
@@ -6270,7 +6446,13 @@ public function testRevealContentWithHiddenParent()
62706446
$this->contentService->revealContent($contents[2]->contentInfo);
62716447

62726448
$parentContent = $this->contentService->loadContent($contents[0]->id);
6273-
$parentLocation = $this->locationService->loadLocation($parentContent->contentInfo->mainLocationId);
6449+
$parentContentMainLocationId = $parentContent->getContentInfo()->getMainLocationId();
6450+
6451+
self::assertNotNull(
6452+
$parentContentMainLocationId,
6453+
'Expected mainLocationId to be set for this test case.'
6454+
);
6455+
$parentLocation = $this->locationService->loadLocation($parentContentMainLocationId);
62746456
$parentSublocations = $this->locationService->loadLocationList([
62756457
$contents[1]->contentInfo->mainLocationId,
62766458
$contents[2]->contentInfo->mainLocationId,
@@ -6328,10 +6510,20 @@ public function testRevealContentWithHiddenChildren()
63286510
$this->contentService->revealContent($contents[0]->contentInfo);
63296511

63306512
$directChildContent = $this->contentService->loadContent($contents[1]->id);
6331-
$directChildLocation = $this->locationService->loadLocation($directChildContent->contentInfo->mainLocationId);
6513+
$directChildContentMainLocationId = $directChildContent->getContentInfo()->getMainLocationId();
6514+
self::assertNotNull(
6515+
$directChildContentMainLocationId,
6516+
'Expected mainLocationId to be set for this test case.'
6517+
);
6518+
$directChildLocation = $this->locationService->loadLocation($directChildContentMainLocationId);
63326519

63336520
$childContent = $this->contentService->loadContent($contents[2]->id);
6334-
$childLocation = $this->locationService->loadLocation($childContent->contentInfo->mainLocationId);
6521+
$childContentMainLocationId = $childContent->getContentInfo()->getMainLocationId();
6522+
self::assertNotNull(
6523+
$childContentMainLocationId,
6524+
'Expected mainLocationId to be set for this test case.'
6525+
);
6526+
$childLocation = $this->locationService->loadLocation($childContentMainLocationId);
63356527
$childSublocations = $this->locationService->loadLocationList([
63366528
$contents[3]->contentInfo->mainLocationId,
63376529
$contents[4]->contentInfo->mainLocationId,

0 commit comments

Comments
 (0)