From b3e770769934f2ef23785983fa9752b55ed6558f Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Fri, 24 Oct 2025 13:40:57 +0200 Subject: [PATCH 01/22] IBX-10854: Not possible to hide content draft --- src/lib/Repository/ContentService.php | 38 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 9c4fe46152..20678b6d79 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2531,14 +2531,17 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ */ public function hideContent(ContentInfo $contentInfo): void { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + // If content is in draft state, mainLocationId is yet not set + if ($contentInfo->mainLocationId !== null) { + $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + [$locationTarget] + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + } } $this->repository->beginTransaction(); @@ -2571,14 +2574,17 @@ public function hideContent(ContentInfo $contentInfo): void */ public function revealContent(ContentInfo $contentInfo): void { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + // If content is in draft state, mainLocationId is yet not set + if ($contentInfo->mainLocationId !== null) { + $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + [$locationTarget] + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + } } $this->repository->beginTransaction(); From 37f717f33a551384340cd17cbd7d335543c9c294 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Fri, 24 Oct 2025 14:13:16 +0200 Subject: [PATCH 02/22] Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index b609acec3c..a6e7f73a3d 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6229,6 +6229,76 @@ function (Location $parentLocation) { $this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal); } + /** + * @covers \Ibexa\Contracts\Core\Repository\ContentService::hideContent + + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException + */ + public function testHideContentDraft(): void + { + $publishedContent = $this->createContentForHideRevealDraftTests(false); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); + self::assertTrue($location->isHidden(), 'Location is visible'); + } + + /** + * @covers \Ibexa\Contracts\Core\Repository\ContentService::revealContent + + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + */ + public function testHideAndRevealContentDraft(): void + { + $publishedContent = $this->createContentForHideRevealDraftTests(true); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); + self::assertFalse($location->isHidden(), 'Location is hidden'); + } + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException + */ + private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content + { + $contentTypeService = $this->getRepository()->getContentTypeService(); + + $locationCreateStructs = $this->locationService->newLocationCreateStruct(2); + + $contentType = $contentTypeService->loadContentTypeByIdentifier('folder'); + + $contentCreate = $this->contentService->newContentCreateStruct($contentType, self::ENG_US); + $contentCreate->setField('name', 'Folder to hide'); + + $draft = $this->contentService->createContent( + $contentCreate, + [$locationCreateStructs] + ); + + $this->contentService->hideContent($draft->contentInfo); + if ($hideAndRevel) { + $this->contentService->revealContent($draft->contentInfo); + } + + return $this->contentService->publishVersion($draft->versionInfo); + } + /** * @depends testRevealContent */ From 70d5de8c550fe689c6a809d8e6a5f9c22ce96918 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Mon, 27 Oct 2025 12:53:21 +0100 Subject: [PATCH 03/22] fixup! IBX-10854: Not possible to hide content draft --- src/lib/Repository/ContentService.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 20678b6d79..342fa33aa6 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2531,8 +2531,8 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ */ public function hideContent(ContentInfo $contentInfo): void { - // If content is in draft state, mainLocationId is yet not set - if ($contentInfo->mainLocationId !== null) { + // If ContentInfo is in draft state, mainLocationId is yet not set + if (!$contentInfo->isDraft()) { $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); if (!$this->permissionResolver->canUser( 'content', @@ -2574,8 +2574,8 @@ public function hideContent(ContentInfo $contentInfo): void */ public function revealContent(ContentInfo $contentInfo): void { - // If content is in draft state, mainLocationId is yet not set - if ($contentInfo->mainLocationId !== null) { + // If ContentInfo is in draft state, mainLocationId is yet not set + if (!$contentInfo->isDraft()) { $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); if (!$this->permissionResolver->canUser( 'content', From 2f5ff0e87e113e659b733560499e020db832ae8b Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 10 Feb 2026 12:35:51 +0100 Subject: [PATCH 04/22] fixup! IBX-10854: Not possible to hide content draft --- src/lib/Repository/ContentService.php | 43 ++++++++++++++------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 342fa33aa6..619cf7a13b 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2531,17 +2531,17 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ */ public function hideContent(ContentInfo $contentInfo): void { - // If ContentInfo is in draft state, mainLocationId is yet not set - if (!$contentInfo->isDraft()) { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); - } + // If ContentInfo is in draft state, mainocationId is yet not set + $locationTarget = !$contentInfo->isDraft() + ? [new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)] + : []; + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + $locationTarget + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); } $this->repository->beginTransaction(); @@ -2575,16 +2575,17 @@ public function hideContent(ContentInfo $contentInfo): void public function revealContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set - if (!$contentInfo->isDraft()) { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); - } + $locationTarget = !$contentInfo->isDraft() + ? [new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)] + : []; + + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + [$locationTarget] + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); } $this->repository->beginTransaction(); From 79d1d5d31e5afdca6be4ae8a4d0c8ce5689557c3 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 10 Feb 2026 15:05:18 +0100 Subject: [PATCH 05/22] fixup! fixup! IBX-10854: Not possible to hide content draft --- src/lib/Repository/ContentService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 619cf7a13b..a380667e03 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2583,7 +2583,7 @@ public function revealContent(ContentInfo $contentInfo): void 'content', 'hide', $contentInfo, - [$locationTarget] + $locationTarget )) { throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); } From 7ec84c3a0647e0d57a20c99d155d65f12973e604 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 10 Feb 2026 15:13:49 +0100 Subject: [PATCH 06/22] fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index a6e7f73a3d..463cb9f6dc 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6230,20 +6230,17 @@ function (Location $parentLocation) { } /** - * @covers \Ibexa\Contracts\Core\Repository\ContentService::hideContent - - * - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws BadStateException + * @throws ContentFieldValidationException + * @throws NotFoundException + * @throws UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); - $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); $content = $this->contentService->loadContent($publishedContent->contentInfo->id); self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); @@ -6260,7 +6257,8 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); - $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); $content = $this->contentService->loadContent($publishedContent->contentInfo->id); self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); @@ -6268,11 +6266,11 @@ public function testHideAndRevealContentDraft(): void } /** - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws APIInvalidArgumentException + * @throws BadStateException + * @throws ContentFieldValidationException + * @throws NotFoundException + * @throws UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content From 082cdc4f60ff41fe055d440ced06d31ada6b4abf Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 10 Feb 2026 15:14:06 +0100 Subject: [PATCH 07/22] Fixed PHPstan --- phpstan-baseline.neon | 5 --- .../Core/Repository/ContentServiceTest.php | 35 +++++++++++++------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9bee1e5f4b..ee96de0bc2 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -33782,11 +33782,6 @@ parameters: count: 4 path: tests/integration/Core/Repository/ContentServiceTest.php - - - message: '#^Parameter \#1 \$locationId of method Ibexa\\Contracts\\Core\\Repository\\LocationService\:\:loadLocation\(\) expects int, int\|null given\.$#' - identifier: argument.type - count: 12 - path: tests/integration/Core/Repository/ContentServiceTest.php - message: '#^Parameter \#1 \$locations of method Ibexa\\Tests\\Integration\\Core\\Repository\\ContentServiceTest\:\:filterHiddenLocations\(\) expects array\, iterable\ given\.$#' diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 463cb9f6dc..8b8d286ecc 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -3610,7 +3610,8 @@ public function testLoadRelationsSkipsArchivedContent() $demoDesign ); - $demoDesignLocation = $this->locationService->loadLocation($demoDesign->mainLocationId); + self::assertNotNull($demoDesign->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $demoDesignLocation = $this->locationService->loadLocation($demoDesign->getMainLocationId()); // Trashing Content's last Location will change its status to archived, // in this case relation towards it will not be loaded. @@ -3936,7 +3937,8 @@ public function testLoadReverseRelationsSkipsArchivedContent() $this->contentService->publishVersion($mediaDraft->getVersionInfo()); $this->contentService->publishVersion($demoDesignDraft->getVersionInfo()); - $demoDesignLocation = $this->locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId); + self::assertNotNull($demoDesignDraft->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $demoDesignLocation = $this->locationService->loadLocation($demoDesignDraft->contentInfo->getMainLocationId()); // Trashing Content's last Location will change its status to archived, // in this case relation from it will not be loaded. @@ -4138,7 +4140,8 @@ public function testLoadReverseRelationListSkipsArchivedContent(): void $draft3, ]); - $locationToTrash = $this->locationService->loadLocation($draft3->contentInfo->mainLocationId); + self::assertNotNull($draft3->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $locationToTrash = $this->locationService->loadLocation($draft3->contentInfo->getMainLocationId()); // Trashing Content's last Location will change its status to archived, in this case relation from it will not be loaded. $trashService->trash($locationToTrash); @@ -5100,8 +5103,9 @@ public function testURLAliasesCreatedForNewContent() // Automatically creates a new URLAlias for the content $liveContent = $this->contentService->publishVersion($draft->getVersionInfo()); + self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->mainLocationId + $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() ); $aliases = $urlAliasService->listLocationAliases($location, false); @@ -5128,8 +5132,9 @@ public function testURLAliasesCreatedForUpdatedContent() $draft = $this->createUpdatedDraftVersion2(); + self::assertNotNull($draft->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation( - $draft->getVersionInfo()->getContentInfo()->mainLocationId + $draft->getVersionInfo()->getContentInfo()->getMainLocationId() ); // Load and assert URL aliases before publishing updated Content, so that @@ -5156,8 +5161,9 @@ public function testURLAliasesCreatedForUpdatedContent() // and creates new aliases, based on the changes $liveContent = $this->contentService->publishVersion($draft->getVersionInfo()); + self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->mainLocationId + $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() ); $aliases = $urlAliasService->listLocationAliases($location, false); @@ -5195,10 +5201,11 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent() $content = $this->createContentVersion1(); + self::assertNotNull($content->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); // Create a custom URL alias $urlAliasService->createUrlAlias( $this->locationService->loadLocation( - $content->getVersionInfo()->getContentInfo()->mainLocationId + $content->getVersionInfo()->getContentInfo()->getMainLocationId() ), '/my/fancy/story-about-ibexa-dxp', self::ENG_US @@ -5219,8 +5226,9 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent() // the custom one is left untouched $liveContent = $this->contentService->publishVersion($draftVersion2->getVersionInfo()); + self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->mainLocationId + $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() ); $aliases = $urlAliasService->listLocationAliases($location); @@ -5391,7 +5399,8 @@ public function testDeleteTranslationUpdatesUrlAlias() $urlAliasService = $this->getRepository()->getURLAliasService(); $content = $this->createContentVersion2(); - $mainLocation = $this->locationService->loadLocation($content->contentInfo->mainLocationId); + self::assertNotNull($content->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $mainLocation = $this->locationService->loadLocation($content->contentInfo->getMainLocationId()); // create custom URL alias for Content main Location $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', self::ENG_GB); @@ -6338,7 +6347,9 @@ public function testRevealContentWithHiddenParent() $this->contentService->revealContent($contents[2]->contentInfo); $parentContent = $this->contentService->loadContent($contents[0]->id); - $parentLocation = $this->locationService->loadLocation($parentContent->contentInfo->mainLocationId); + + self::assertNotNull($parentContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $parentLocation = $this->locationService->loadLocation($parentContent->contentInfo->getMainLocationId()); $parentSublocations = $this->locationService->loadLocationList([ $contents[1]->contentInfo->mainLocationId, $contents[2]->contentInfo->mainLocationId, @@ -6396,9 +6407,11 @@ public function testRevealContentWithHiddenChildren() $this->contentService->revealContent($contents[0]->contentInfo); $directChildContent = $this->contentService->loadContent($contents[1]->id); - $directChildLocation = $this->locationService->loadLocation($directChildContent->contentInfo->mainLocationId); + self::assertNotNull($directChildContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $directChildLocation = $this->locationService->loadLocation($directChildContent->contentInfo->getMainLocationId()); $childContent = $this->contentService->loadContent($contents[2]->id); + self::assertNotNull($childContent->contentInfo->mainLocationId, 'Expected mainLocationId to be set for this test case.'); $childLocation = $this->locationService->loadLocation($childContent->contentInfo->mainLocationId); $childSublocations = $this->locationService->loadLocationList([ $contents[3]->contentInfo->mainLocationId, From bdcfc49e0dc41a73514c2fc21f8ef8e5c1d53f03 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 10 Feb 2026 15:14:57 +0100 Subject: [PATCH 08/22] fixup! fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 8b8d286ecc..a8d5a73abc 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6239,10 +6239,10 @@ function (Location $parentLocation) { } /** - * @throws BadStateException - * @throws ContentFieldValidationException - * @throws NotFoundException - * @throws UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ public function testHideContentDraft(): void @@ -6275,11 +6275,11 @@ public function testHideAndRevealContentDraft(): void } /** - * @throws APIInvalidArgumentException - * @throws BadStateException - * @throws ContentFieldValidationException - * @throws NotFoundException - * @throws UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content From 510f0fc3cfad608cf0e366fdde6875364f07cb78 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 24 Feb 2026 15:57:04 +0100 Subject: [PATCH 09/22] fixup! fixup! fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index a8d5a73abc..034d53b579 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6248,11 +6248,9 @@ function (Location $parentLocation) { public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); - self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - $content = $this->contentService->loadContent($publishedContent->contentInfo->id); - self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); + self::assertTrue($publishedContent->contentInfo->isHidden, 'Content is not hidden'); self::assertTrue($location->isHidden(), 'Location is visible'); } @@ -6266,11 +6264,9 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); - self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - $content = $this->contentService->loadContent($publishedContent->contentInfo->id); - self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); + self::assertFalse($publishedContent->contentInfo->isHidden, 'Content is hidden'); self::assertFalse($location->isHidden(), 'Location is hidden'); } @@ -6282,7 +6278,7 @@ public function testHideAndRevealContentDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content + private function createContentForHideRevealDraftTests(bool $hideAndReveal): Content { $contentTypeService = $this->getRepository()->getContentTypeService(); @@ -6299,11 +6295,14 @@ private function createContentForHideRevealDraftTests(bool $hideAndRevel): Conte ); $this->contentService->hideContent($draft->contentInfo); - if ($hideAndRevel) { + if ($hideAndReveal) { $this->contentService->revealContent($draft->contentInfo); } - return $this->contentService->publishVersion($draft->versionInfo); + $publishedContent = $this->contentService->publishVersion($draft->versionInfo); + self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + + return $publishedContent; } /** From 17caab80cc0ec0f9391934cff7cd9636934da1f6 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Tue, 24 Feb 2026 16:12:37 +0100 Subject: [PATCH 10/22] Revert "fixup! fixup! fixup! Added tests for IBX-10854: Not possible to hide content draft" This reverts commit 0de3f326625b4a64df4d53c51574f5a62980bb4e. --- .../Core/Repository/ContentServiceTest.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 034d53b579..a8d5a73abc 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6248,9 +6248,11 @@ function (Location $parentLocation) { public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); + self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - self::assertTrue($publishedContent->contentInfo->isHidden, 'Content is not hidden'); + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); self::assertTrue($location->isHidden(), 'Location is visible'); } @@ -6264,9 +6266,11 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); + self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - self::assertFalse($publishedContent->contentInfo->isHidden, 'Content is hidden'); + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); self::assertFalse($location->isHidden(), 'Location is hidden'); } @@ -6278,7 +6282,7 @@ public function testHideAndRevealContentDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - private function createContentForHideRevealDraftTests(bool $hideAndReveal): Content + private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content { $contentTypeService = $this->getRepository()->getContentTypeService(); @@ -6295,14 +6299,11 @@ private function createContentForHideRevealDraftTests(bool $hideAndReveal): Cont ); $this->contentService->hideContent($draft->contentInfo); - if ($hideAndReveal) { + if ($hideAndRevel) { $this->contentService->revealContent($draft->contentInfo); } - $publishedContent = $this->contentService->publishVersion($draft->versionInfo); - self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - - return $publishedContent; + return $this->contentService->publishVersion($draft->versionInfo); } /** From f4ed055aff27027372cfa620d1ed868444d25459 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Fri, 6 Mar 2026 12:57:37 +0100 Subject: [PATCH 11/22] Apply suggestions from code review for Tests Co-authored-by: Konrad Oboza --- .../Core/Repository/ContentServiceTest.php | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index a8d5a73abc..ed44735c23 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -5399,7 +5399,10 @@ public function testDeleteTranslationUpdatesUrlAlias() $urlAliasService = $this->getRepository()->getURLAliasService(); $content = $this->createContentVersion2(); - self::assertNotNull($content->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + self::assertNotNull( + $content->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); $mainLocation = $this->locationService->loadLocation($content->contentInfo->getMainLocationId()); // create custom URL alias for Content main Location @@ -6248,11 +6251,14 @@ function (Location $parentLocation) { public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); - self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + self::assertNotNull( + $publishedContent->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - $content = $this->contentService->loadContent($publishedContent->contentInfo->id); - self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); + $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); + self::assertTrue($content->contentInfo->isHidden(), 'Content is not hidden'); self::assertTrue($location->isHidden(), 'Location is visible'); } @@ -6266,11 +6272,14 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); - self::assertNotNull($publishedContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + self::assertNotNull( + $publishedContent->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); - $content = $this->contentService->loadContent($publishedContent->contentInfo->id); - self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); + $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); + self::assertFalse($content->contentInfo->isHidden(), 'Content is hidden'); self::assertFalse($location->isHidden(), 'Location is hidden'); } @@ -6348,7 +6357,10 @@ public function testRevealContentWithHiddenParent() $parentContent = $this->contentService->loadContent($contents[0]->id); - self::assertNotNull($parentContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + self::assertNotNull( + $parentContent->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); $parentLocation = $this->locationService->loadLocation($parentContent->contentInfo->getMainLocationId()); $parentSublocations = $this->locationService->loadLocationList([ $contents[1]->contentInfo->mainLocationId, @@ -6407,11 +6419,19 @@ public function testRevealContentWithHiddenChildren() $this->contentService->revealContent($contents[0]->contentInfo); $directChildContent = $this->contentService->loadContent($contents[1]->id); - self::assertNotNull($directChildContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $directChildLocation = $this->locationService->loadLocation($directChildContent->contentInfo->getMainLocationId()); + self::assertNotNull( + $directChildContent->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); + $directChildLocation = $this->locationService->loadLocation( + $directChildContent->contentInfo->getMainLocationId() + ); $childContent = $this->contentService->loadContent($contents[2]->id); - self::assertNotNull($childContent->contentInfo->mainLocationId, 'Expected mainLocationId to be set for this test case.'); + self::assertNotNull( + $childContent->contentInfo->getMainLocationId(), + 'Expected mainLocationId to be set for this test case.' + ); $childLocation = $this->locationService->loadLocation($childContent->contentInfo->mainLocationId); $childSublocations = $this->locationService->loadLocationList([ $contents[3]->contentInfo->mainLocationId, From ecb639fdfea5c592e40854725cf91b3fa1d1e6bb Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Fri, 6 Mar 2026 12:58:08 +0100 Subject: [PATCH 12/22] Apply suggestions from code review Co-authored-by: Konrad Oboza --- src/lib/Repository/ContentService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index a380667e03..f7e9eb1e94 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2531,7 +2531,7 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ */ public function hideContent(ContentInfo $contentInfo): void { - // If ContentInfo is in draft state, mainocationId is yet not set + // If ContentInfo is in draft state, mainLocationId is yet not set $locationTarget = !$contentInfo->isDraft() ? [new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)] : []; From bc5306cc673024ba87e222510ec9e99202052dea Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Mon, 9 Mar 2026 14:45:19 +0100 Subject: [PATCH 13/22] fixup! Apply suggestions from code review for Tests --- tests/integration/Core/Repository/ContentServiceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index ed44735c23..5e7e4d9923 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6432,7 +6432,7 @@ public function testRevealContentWithHiddenChildren() $childContent->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.' ); - $childLocation = $this->locationService->loadLocation($childContent->contentInfo->mainLocationId); + $childLocation = $this->locationService->loadLocation($childContent->contentInfo->getMainLocationId()); $childSublocations = $this->locationService->loadLocationList([ $contents[3]->contentInfo->mainLocationId, $contents[4]->contentInfo->mainLocationId, From d82173c84b0f548be5ee0acbb8c2113cfa302627 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 11 Mar 2026 11:26:50 +0100 Subject: [PATCH 14/22] fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 5e7e4d9923..37f288e809 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -3610,8 +3610,9 @@ public function testLoadRelationsSkipsArchivedContent() $demoDesign ); - self::assertNotNull($demoDesign->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $demoDesignLocation = $this->locationService->loadLocation($demoDesign->getMainLocationId()); + $demoDesignMainLocationId = $demoDesign->getMainLocationId(); + self::assertNotNull($demoDesignMainLocationId, 'Expected mainLocationId to be set for this test case.'); + $demoDesignLocation = $this->locationService->loadLocation($demoDesignMainLocationId); // Trashing Content's last Location will change its status to archived, // in this case relation towards it will not be loaded. @@ -3937,8 +3938,9 @@ public function testLoadReverseRelationsSkipsArchivedContent() $this->contentService->publishVersion($mediaDraft->getVersionInfo()); $this->contentService->publishVersion($demoDesignDraft->getVersionInfo()); - self::assertNotNull($demoDesignDraft->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $demoDesignLocation = $this->locationService->loadLocation($demoDesignDraft->contentInfo->getMainLocationId()); + $demoDesignLocationId = $demoDesignDraft->contentInfo->getMainLocationId(); + self::assertNotNull($demoDesignLocationId, 'Expected mainLocationId to be set for this test case.'); + $demoDesignLocation = $this->locationService->loadLocation($demoDesignLocationId); // Trashing Content's last Location will change its status to archived, // in this case relation from it will not be loaded. @@ -4140,8 +4142,9 @@ public function testLoadReverseRelationListSkipsArchivedContent(): void $draft3, ]); - self::assertNotNull($draft3->contentInfo->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $locationToTrash = $this->locationService->loadLocation($draft3->contentInfo->getMainLocationId()); + $draft3MainLocationId = $draft3->contentInfo->getMainLocationId(); + self::assertNotNull($draft3MainLocationId, 'Expected mainLocationId to be set for this test case.'); + $locationToTrash = $this->locationService->loadLocation($draft3MainLocationId); // Trashing Content's last Location will change its status to archived, in this case relation from it will not be loaded. $trashService->trash($locationToTrash); @@ -5103,10 +5106,9 @@ public function testURLAliasesCreatedForNewContent() // Automatically creates a new URLAlias for the content $liveContent = $this->contentService->publishVersion($draft->getVersionInfo()); - self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() - ); + $liveContentInfoMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(); + self::assertNotNull($liveContentInfoMainLocationId, 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($liveContentInfoMainLocationId); $aliases = $urlAliasService->listLocationAliases($location, false); @@ -5132,10 +5134,9 @@ public function testURLAliasesCreatedForUpdatedContent() $draft = $this->createUpdatedDraftVersion2(); - self::assertNotNull($draft->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $location = $this->locationService->loadLocation( - $draft->getVersionInfo()->getContentInfo()->getMainLocationId() - ); + $draftMainLocationId = $draft->getVersionInfo()->getContentInfo()->getMainLocationId(); + self::assertNotNull($draftMainLocationId, 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($draftMainLocationId); // Load and assert URL aliases before publishing updated Content, so that // SPI cache is warmed up and cache invalidation is also tested. @@ -5161,10 +5162,9 @@ public function testURLAliasesCreatedForUpdatedContent() // and creates new aliases, based on the changes $liveContent = $this->contentService->publishVersion($draft->getVersionInfo()); - self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() - ); + $liveContentInfoMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(); + self::assertNotNull($liveContentInfoMainLocationId, 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($liveContentInfoMainLocationId); $aliases = $urlAliasService->listLocationAliases($location, false); @@ -5201,12 +5201,11 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent() $content = $this->createContentVersion1(); - self::assertNotNull($content->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); + $contentMainLocationId = $content->getVersionInfo()->getContentInfo()->getMainLocationId(); + self::assertNotNull($contentMainLocationId, 'Expected mainLocationId to be set for this test case.'); // Create a custom URL alias $urlAliasService->createUrlAlias( - $this->locationService->loadLocation( - $content->getVersionInfo()->getContentInfo()->getMainLocationId() - ), + $this->locationService->loadLocation($contentMainLocationId), '/my/fancy/story-about-ibexa-dxp', self::ENG_US ); @@ -5226,10 +5225,9 @@ public function testCustomURLAliasesNotHistorizedOnUpdatedContent() // the custom one is left untouched $liveContent = $this->contentService->publishVersion($draftVersion2->getVersionInfo()); - self::assertNotNull($liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(), 'Expected mainLocationId to be set for this test case.'); - $location = $this->locationService->loadLocation( - $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId() - ); + $liveContentMainLocationId = $liveContent->getVersionInfo()->getContentInfo()->getMainLocationId(); + self::assertNotNull($liveContentMainLocationId, 'Expected mainLocationId to be set for this test case.'); + $location = $this->locationService->loadLocation($liveContentMainLocationId); $aliases = $urlAliasService->listLocationAliases($location); @@ -5399,11 +5397,12 @@ public function testDeleteTranslationUpdatesUrlAlias() $urlAliasService = $this->getRepository()->getURLAliasService(); $content = $this->createContentVersion2(); + $contentMainLocationId = $content->getContentInfo()->getMainLocationId(); self::assertNotNull( - $content->contentInfo->getMainLocationId(), + $contentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $mainLocation = $this->locationService->loadLocation($content->contentInfo->getMainLocationId()); + $mainLocation = $this->locationService->loadLocation($contentMainLocationId); // create custom URL alias for Content main Location $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', self::ENG_GB); @@ -6251,11 +6250,12 @@ function (Location $parentLocation) { public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); + $publishedContentMainLocationId = $publishedContent->contentInfo->getMainLocationId(); self::assertNotNull( - $publishedContent->contentInfo->getMainLocationId(), + $publishedContentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); + $location = $this->locationService->loadLocation($publishedContentMainLocationId); $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); self::assertTrue($content->contentInfo->isHidden(), 'Content is not hidden'); @@ -6272,11 +6272,12 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); + $publishedContentMainLocationId = $publishedContent->contentInfo->getMainLocationId(); self::assertNotNull( - $publishedContent->contentInfo->getMainLocationId(), + $publishedContentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $location = $this->locationService->loadLocation($publishedContent->contentInfo->getMainLocationId()); + $location = $this->locationService->loadLocation($publishedContentMainLocationId); $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); self::assertFalse($content->contentInfo->isHidden(), 'Content is hidden'); @@ -6291,12 +6292,10 @@ public function testHideAndRevealContentDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content + private function createContentForHideRevealDraftTests(bool $revel): Content { $contentTypeService = $this->getRepository()->getContentTypeService(); - $locationCreateStructs = $this->locationService->newLocationCreateStruct(2); - $contentType = $contentTypeService->loadContentTypeByIdentifier('folder'); $contentCreate = $this->contentService->newContentCreateStruct($contentType, self::ENG_US); @@ -6308,7 +6307,7 @@ private function createContentForHideRevealDraftTests(bool $hideAndRevel): Conte ); $this->contentService->hideContent($draft->contentInfo); - if ($hideAndRevel) { + if ($revel) { $this->contentService->revealContent($draft->contentInfo); } @@ -6356,12 +6355,13 @@ public function testRevealContentWithHiddenParent() $this->contentService->revealContent($contents[2]->contentInfo); $parentContent = $this->contentService->loadContent($contents[0]->id); + $parentContentMainLocationId = $parentContent->contentInfo->getMainLocationId(); self::assertNotNull( - $parentContent->contentInfo->getMainLocationId(), + $parentContentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $parentLocation = $this->locationService->loadLocation($parentContent->contentInfo->getMainLocationId()); + $parentLocation = $this->locationService->loadLocation($parentContentMainLocationId); $parentSublocations = $this->locationService->loadLocationList([ $contents[1]->contentInfo->mainLocationId, $contents[2]->contentInfo->mainLocationId, @@ -6419,20 +6419,20 @@ public function testRevealContentWithHiddenChildren() $this->contentService->revealContent($contents[0]->contentInfo); $directChildContent = $this->contentService->loadContent($contents[1]->id); + $directChildContentMainLocationId = $directChildContent->contentInfo->getMainLocationId(); self::assertNotNull( - $directChildContent->contentInfo->getMainLocationId(), + $directChildContentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $directChildLocation = $this->locationService->loadLocation( - $directChildContent->contentInfo->getMainLocationId() - ); + $directChildLocation = $this->locationService->loadLocation($directChildContentMainLocationId); $childContent = $this->contentService->loadContent($contents[2]->id); + $childContentMainLocationId = $childContent->contentInfo->getMainLocationId(); self::assertNotNull( - $childContent->contentInfo->getMainLocationId(), + $childContentMainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $childLocation = $this->locationService->loadLocation($childContent->contentInfo->getMainLocationId()); + $childLocation = $this->locationService->loadLocation($childContentMainLocationId); $childSublocations = $this->locationService->loadLocationList([ $contents[3]->contentInfo->mainLocationId, $contents[4]->contentInfo->mainLocationId, From a2b955078fa47fb496d4cf995aaa58c914f053a3 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 11 Mar 2026 12:10:34 +0100 Subject: [PATCH 15/22] fixup! fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 37f288e809..606a84ebbd 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -3938,7 +3938,7 @@ public function testLoadReverseRelationsSkipsArchivedContent() $this->contentService->publishVersion($mediaDraft->getVersionInfo()); $this->contentService->publishVersion($demoDesignDraft->getVersionInfo()); - $demoDesignLocationId = $demoDesignDraft->contentInfo->getMainLocationId(); + $demoDesignLocationId = $demoDesignDraft->getContentInfo()->getMainLocationId(); self::assertNotNull($demoDesignLocationId, 'Expected mainLocationId to be set for this test case.'); $demoDesignLocation = $this->locationService->loadLocation($demoDesignLocationId); @@ -4142,7 +4142,7 @@ public function testLoadReverseRelationListSkipsArchivedContent(): void $draft3, ]); - $draft3MainLocationId = $draft3->contentInfo->getMainLocationId(); + $draft3MainLocationId = $draft3->getContentInfo()->getMainLocationId(); self::assertNotNull($draft3MainLocationId, 'Expected mainLocationId to be set for this test case.'); $locationToTrash = $this->locationService->loadLocation($draft3MainLocationId); @@ -6250,7 +6250,7 @@ function (Location $parentLocation) { public function testHideContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(false); - $publishedContentMainLocationId = $publishedContent->contentInfo->getMainLocationId(); + $publishedContentMainLocationId = $publishedContent->getContentInfo()->getMainLocationId(); self::assertNotNull( $publishedContentMainLocationId, 'Expected mainLocationId to be set for this test case.' @@ -6272,7 +6272,7 @@ public function testHideContentDraft(): void public function testHideAndRevealContentDraft(): void { $publishedContent = $this->createContentForHideRevealDraftTests(true); - $publishedContentMainLocationId = $publishedContent->contentInfo->getMainLocationId(); + $publishedContentMainLocationId = $publishedContent->getContentInfo()->getMainLocationId(); self::assertNotNull( $publishedContentMainLocationId, 'Expected mainLocationId to be set for this test case.' @@ -6355,7 +6355,7 @@ public function testRevealContentWithHiddenParent() $this->contentService->revealContent($contents[2]->contentInfo); $parentContent = $this->contentService->loadContent($contents[0]->id); - $parentContentMainLocationId = $parentContent->contentInfo->getMainLocationId(); + $parentContentMainLocationId = $parentContent->getContentInfo()->getMainLocationId(); self::assertNotNull( $parentContentMainLocationId, @@ -6419,7 +6419,7 @@ public function testRevealContentWithHiddenChildren() $this->contentService->revealContent($contents[0]->contentInfo); $directChildContent = $this->contentService->loadContent($contents[1]->id); - $directChildContentMainLocationId = $directChildContent->contentInfo->getMainLocationId(); + $directChildContentMainLocationId = $directChildContent->getContentInfo()->getMainLocationId(); self::assertNotNull( $directChildContentMainLocationId, 'Expected mainLocationId to be set for this test case.' @@ -6427,7 +6427,7 @@ public function testRevealContentWithHiddenChildren() $directChildLocation = $this->locationService->loadLocation($directChildContentMainLocationId); $childContent = $this->contentService->loadContent($contents[2]->id); - $childContentMainLocationId = $childContent->contentInfo->getMainLocationId(); + $childContentMainLocationId = $childContent->getContentInfo()->getMainLocationId(); self::assertNotNull( $childContentMainLocationId, 'Expected mainLocationId to be set for this test case.' From b2ffb94a5fb62e64e482d2d6e4020c850950b632 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 11 Mar 2026 12:28:14 +0100 Subject: [PATCH 16/22] fixup! fixup! Added tests for IBX-10854: Not possible to hide content draft --- .../Core/Repository/ContentServiceTest.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 606a84ebbd..c45408de2f 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6257,8 +6257,8 @@ public function testHideContentDraft(): void ); $location = $this->locationService->loadLocation($publishedContentMainLocationId); - $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); - self::assertTrue($content->contentInfo->isHidden(), 'Content is not hidden'); + $content = $this->contentService->loadContent($publishedContent->getContentInfo()->getId()); + self::assertTrue($content->getContentInfo()->isHidden(), 'Content is not hidden'); self::assertTrue($location->isHidden(), 'Location is visible'); } @@ -6279,8 +6279,8 @@ public function testHideAndRevealContentDraft(): void ); $location = $this->locationService->loadLocation($publishedContentMainLocationId); - $content = $this->contentService->loadContent($publishedContent->contentInfo->getId()); - self::assertFalse($content->contentInfo->isHidden(), 'Content is hidden'); + $content = $this->contentService->loadContent($publishedContent->getContentInfo()->getId()); + self::assertFalse($content->getContentInfo()->isHidden(), 'Content is hidden'); self::assertFalse($location->isHidden(), 'Location is hidden'); } @@ -6306,12 +6306,13 @@ private function createContentForHideRevealDraftTests(bool $revel): Content [$locationCreateStructs] ); - $this->contentService->hideContent($draft->contentInfo); + $draftContentInfo = $draft->getContentInfo(); + $this->contentService->hideContent($draftContentInfo); if ($revel) { - $this->contentService->revealContent($draft->contentInfo); + $this->contentService->revealContent($draftContentInfo); } - return $this->contentService->publishVersion($draft->versionInfo); + return $this->contentService->publishVersion($draft->getVersionInfo()); } /** From 8a4ab35913094926632aa4825b08205ba6d9dde0 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 11 Mar 2026 12:32:16 +0100 Subject: [PATCH 17/22] fixup! IBX-10854: Not possible to hide content draft --- src/lib/Repository/ContentService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index f7e9eb1e94..fc7af5129f 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2533,7 +2533,7 @@ public function hideContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set $locationTarget = !$contentInfo->isDraft() - ? [new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)] + ? [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)] : []; if (!$this->permissionResolver->canUser( 'content', @@ -2576,7 +2576,7 @@ public function revealContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set $locationTarget = !$contentInfo->isDraft() - ? [new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)] + ? [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)] : []; if (!$this->permissionResolver->canUser( From c6617ffda06f14862d91821ebb5f626c8fc7c37c Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Mon, 20 Apr 2026 16:49:11 +0200 Subject: [PATCH 18/22] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paweł Niedzielski Co-authored-by: Konrad Oboza --- src/lib/Repository/ContentService.php | 6 +++--- tests/integration/Core/Repository/ContentServiceTest.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index fc7af5129f..a4831ce62e 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2575,9 +2575,9 @@ public function hideContent(ContentInfo $contentInfo): void public function revealContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set - $locationTarget = !$contentInfo->isDraft() - ? [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)] - : []; + $locationTarget = $contentInfo->isDraft() + ? [] + : [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)]; if (!$this->permissionResolver->canUser( 'content', diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index c45408de2f..1b6d5019ea 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6292,7 +6292,7 @@ public function testHideAndRevealContentDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - private function createContentForHideRevealDraftTests(bool $revel): Content + private function createContentForHideRevealDraftTests(bool $reveal): Content { $contentTypeService = $this->getRepository()->getContentTypeService(); $locationCreateStructs = $this->locationService->newLocationCreateStruct(2); @@ -6308,7 +6308,7 @@ private function createContentForHideRevealDraftTests(bool $revel): Content $draftContentInfo = $draft->getContentInfo(); $this->contentService->hideContent($draftContentInfo); - if ($revel) { + if ($reveal) { $this->contentService->revealContent($draftContentInfo); } From 17173e98cf9b1834acd0b9f2c7949c1c6c8b51a9 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Mon, 20 Apr 2026 16:50:19 +0200 Subject: [PATCH 19/22] fixup! Apply suggestions from code review --- src/lib/Repository/ContentService.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index a4831ce62e..7ca90dbd53 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2532,9 +2532,9 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ public function hideContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set - $locationTarget = !$contentInfo->isDraft() - ? [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)] - : []; + $locationTarget = $contentInfo->isDraft() + ? [] + : [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)]; if (!$this->permissionResolver->canUser( 'content', 'hide', From 57300ead2d7bf1fe0dab75dd0e8d73398df975c9 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 20 May 2026 13:32:49 +0200 Subject: [PATCH 20/22] Apply suggestions from code review --- src/lib/Repository/ContentService.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 7ca90dbd53..e4792e39aa 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2532,14 +2532,14 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ public function hideContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set - $locationTarget = $contentInfo->isDraft() + $targets = $contentInfo->isDraft() ? [] : [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)]; if (!$this->permissionResolver->canUser( 'content', 'hide', $contentInfo, - $locationTarget + $targets )) { throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); } @@ -2575,7 +2575,7 @@ public function hideContent(ContentInfo $contentInfo): void public function revealContent(ContentInfo $contentInfo): void { // If ContentInfo is in draft state, mainLocationId is yet not set - $locationTarget = $contentInfo->isDraft() + $targets = $contentInfo->isDraft() ? [] : [new DestinationLocationTarget($contentInfo->getMainLocationId(), $contentInfo)]; @@ -2583,7 +2583,7 @@ public function revealContent(ContentInfo $contentInfo): void 'content', 'hide', $contentInfo, - $locationTarget + $targets )) { throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); } From 14e3fdd660161aaefc0fbbd3cb252e221e2f93ef Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 20 May 2026 13:28:31 +0200 Subject: [PATCH 21/22] Apply suggestions from code review on tests --- .../Core/Repository/ContentServiceTest.php | 98 ++++++++++++++----- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 1b6d5019ea..0990d988da 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6241,46 +6241,66 @@ function (Location $parentLocation) { } /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - public function testHideContentDraft(): void + public function testPublishHiddenDraft(): void { - $publishedContent = $this->createContentForHideRevealDraftTests(false); - $publishedContentMainLocationId = $publishedContent->getContentInfo()->getMainLocationId(); + $draft = $this->createFolderDraft(); + $draftContentInfo = $draft->getContentInfo(); + $this->contentService->hideContent($draftContentInfo); + + $publishedContent = $this->contentService->publishVersion($draft->getVersionInfo()); + $contentInfo = $publishedContent->getContentInfo(); + + self::assertTrue($contentInfo->isHidden(), 'Content is not hidden'); + + $mainLocationId = $contentInfo->getMainLocationId(); + self::assertNotNull( - $publishedContentMainLocationId, + $mainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $location = $this->locationService->loadLocation($publishedContentMainLocationId); - $content = $this->contentService->loadContent($publishedContent->getContentInfo()->getId()); - self::assertTrue($content->getContentInfo()->isHidden(), 'Content is not hidden'); + $location = $this->locationService->loadLocation($mainLocationId); self::assertTrue($location->isHidden(), 'Location is visible'); } /** - * @covers \Ibexa\Contracts\Core\Repository\ContentService::revealContent - - * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - public function testHideAndRevealContentDraft(): void + public function testPublishRevealedDraft(): void { - $publishedContent = $this->createContentForHideRevealDraftTests(true); - $publishedContentMainLocationId = $publishedContent->getContentInfo()->getMainLocationId(); + $draft = $this->createFolderDraft(); + $draftContentInfo = $draft->getContentInfo(); + + $this->contentService->hideContent($draftContentInfo); + $this->contentService->revealContent($draftContentInfo); + + $publishedContent = $this->contentService->publishVersion( + $draft->getVersionInfo() + ); + + $contentInfo = $publishedContent->getContentInfo(); + $mainLocationId = $contentInfo->getMainLocationId(); + + self::assertFalse($contentInfo->isHidden(), 'Content is hidden'); self::assertNotNull( - $publishedContentMainLocationId, + $mainLocationId, 'Expected mainLocationId to be set for this test case.' ); - $location = $this->locationService->loadLocation($publishedContentMainLocationId); - $content = $this->contentService->loadContent($publishedContent->getContentInfo()->getId()); - self::assertFalse($content->getContentInfo()->isHidden(), 'Content is hidden'); + $location = $this->locationService->loadLocation($mainLocationId); + self::assertFalse($location->isHidden(), 'Location is hidden'); } @@ -6292,7 +6312,39 @@ public function testHideAndRevealContentDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - private function createContentForHideRevealDraftTests(bool $reveal): Content + public function testHideAndRevealNeverPublishedDraft(): void + { + $draft = $this->createFolderDraft(); + $draftContentInfo = $draft->getContentInfo(); + + $this->contentService->hideContent($draftContentInfo); + + self::assertTrue( + $this->contentService + ->loadContent($draftContentInfo->getId()) + ->getContentInfo() + ->isHidden() + ); + + $this->contentService->revealContent($draftContentInfo); + + self::assertFalse( + $this->contentService + ->loadContent($draftContentInfo->getId()) + ->getContentInfo() + ->isHidden() + ); + } + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException + */ + private function createFolderDraft(): Content { $contentTypeService = $this->getRepository()->getContentTypeService(); $locationCreateStructs = $this->locationService->newLocationCreateStruct(2); @@ -6301,18 +6353,10 @@ private function createContentForHideRevealDraftTests(bool $reveal): Content $contentCreate = $this->contentService->newContentCreateStruct($contentType, self::ENG_US); $contentCreate->setField('name', 'Folder to hide'); - $draft = $this->contentService->createContent( + return $this->contentService->createContent( $contentCreate, [$locationCreateStructs] ); - - $draftContentInfo = $draft->getContentInfo(); - $this->contentService->hideContent($draftContentInfo); - if ($reveal) { - $this->contentService->revealContent($draftContentInfo); - } - - return $this->contentService->publishVersion($draft->getVersionInfo()); } /** From c2ea69b5f6d2d08a38b33a31b1eb0cb441699d91 Mon Sep 17 00:00:00 2001 From: Vidar Langseid Date: Wed, 20 May 2026 15:22:59 +0200 Subject: [PATCH 22/22] fixup! Apply suggestions from code review on tests --- .../Core/Repository/ContentServiceTest.php | 76 +++++++++++++++---- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index 0990d988da..8c7f1ff590 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6284,7 +6284,20 @@ public function testPublishRevealedDraft(): void $draftContentInfo = $draft->getContentInfo(); $this->contentService->hideContent($draftContentInfo); + self::assertTrue( + $this->contentService + ->loadContent($draftContentInfo->getId()) + ->getContentInfo() + ->isHidden() + ); + $this->contentService->revealContent($draftContentInfo); + self::assertFalse( + $this->contentService + ->loadContent($draftContentInfo->getId()) + ->getContentInfo() + ->isHidden() + ); $publishedContent = $this->contentService->publishVersion( $draft->getVersionInfo() @@ -6305,6 +6318,8 @@ public function testPublishRevealedDraft(): void } /** + * @dataProvider draftVisibilityTransitionsProvider + * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException @@ -6312,30 +6327,61 @@ public function testPublishRevealedDraft(): void * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException */ - public function testHideAndRevealNeverPublishedDraft(): void - { + public function testDraftVisibilityTransitions( + bool $initiallyHidden, + bool $secondDraftHidden + ): void { $draft = $this->createFolderDraft(); - $draftContentInfo = $draft->getContentInfo(); - $this->contentService->hideContent($draftContentInfo); + if ($initiallyHidden) { + $this->contentService->hideContent($draft->getContentInfo()); + } - self::assertTrue( - $this->contentService - ->loadContent($draftContentInfo->getId()) - ->getContentInfo() - ->isHidden() + $publishedContent = $this->contentService->publishVersion($draft->getVersionInfo()); + $draft2 = $this->contentService->createContentDraft($publishedContent->getContentInfo()); + + if ($secondDraftHidden) { + $this->contentService->hideContent($draft2->getContentInfo()); + } else { + $this->contentService->revealContent($draft2->getContentInfo()); + } + + $publishedContent2 = $this->contentService->publishVersion($draft2->getVersionInfo()); + $contentInfo = $publishedContent2->getContentInfo(); + + self::assertSame( + $secondDraftHidden, + $contentInfo->isHidden(), + 'Unexpected final hidden state for content.' ); - $this->contentService->revealContent($draftContentInfo); + $mainLocationId = $contentInfo->getMainLocationId(); - self::assertFalse( - $this->contentService - ->loadContent($draftContentInfo->getId()) - ->getContentInfo() - ->isHidden() + self::assertNotNull( + $mainLocationId, + 'Expected mainLocationId to be set.' + ); + + $location = $this->locationService->loadLocation($mainLocationId); + + self::assertSame( + $secondDraftHidden, + $location->isHidden(), + 'Unexpected final hidden state for location.' ); } + /** + * @return iterable + */ + public static function draftVisibilityTransitionsProvider(): iterable + { + yield 'hidden -> hidden' => [true, true]; + yield 'hidden -> visible' => [true, false]; + yield 'visible -> hidden' => [false, true]; + yield 'visible -> visible' => [false, false]; + } + /** * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException