From 4211e0f5af4c832f09b6612ada50e9137dbd8731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Alfonso=20Pym=20Mej=C3=ADa?= Date: Fri, 23 Oct 2026 08:46:44 -0600 Subject: [PATCH] fix(dav): return a list from the share-types property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Mario Alfonso Pym Mejía --- .../dav/lib/Connector/Sabre/ShareTypeList.php | 4 +-- apps/dav/lib/Connector/Sabre/SharesPlugin.php | 2 +- .../unit/Connector/Sabre/SharesPluginTest.php | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/ShareTypeList.php b/apps/dav/lib/Connector/Sabre/ShareTypeList.php index 694c64325131c..907c4ecee7a5b 100644 --- a/apps/dav/lib/Connector/Sabre/ShareTypeList.php +++ b/apps/dav/lib/Connector/Sabre/ShareTypeList.php @@ -21,7 +21,7 @@ class ShareTypeList implements Element { public const NS_OWNCLOUD = 'http://owncloud.org/ns'; /** - * @param int[] $shareTypes + * @param list $shareTypes */ public function __construct( /** @@ -34,7 +34,7 @@ public function __construct( /** * Returns the share types * - * @return int[] + * @return list */ public function getShareTypes() { return $this->shareTypes; diff --git a/apps/dav/lib/Connector/Sabre/SharesPlugin.php b/apps/dav/lib/Connector/Sabre/SharesPlugin.php index d0119bfc577fc..b96ee3ccb2c14 100644 --- a/apps/dav/lib/Connector/Sabre/SharesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/SharesPlugin.php @@ -229,7 +229,7 @@ public function handleGetProperties( $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode): ShareTypeList { $shares = $this->getShares($sabreNode); - $shareTypes = array_unique(array_map(static fn (IShare $share): int => $share->getShareType(), $shares)); + $shareTypes = array_values(array_unique(array_map(static fn (IShare $share): int => $share->getShareType(), $shares))); return new ShareTypeList($shareTypes); }); diff --git a/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php index 20c76e165e738..446a202d1f4ba 100644 --- a/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php @@ -264,6 +264,41 @@ public function testPreloadThenGetProperties(array $shareTypes): void { $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes()); } + public function testGetPropertiesReturnsListWithRepeatedShareTypes(): void { + $sabreNode = $this->createMock(Node::class); + $sabreNode->method('getId')->willReturn(123); + $sabreNode->method('getPath')->willReturn('/subdir'); + $sabreNode->method('getNode')->willReturn($this->createMock(Folder::class)); + + // Two user shares and one link share on the same node + $shareOfType = function (int $type): IShare { + $share = $this->createMock(IShare::class); + $share->method('getShareType')->willReturn($type); + return $share; + }; + $this->shareManager->method('getSharesBy') + ->willReturnCallback(fn ($userId, int $requestedShareType) => match ($requestedShareType) { + IShare::TYPE_USER => [$shareOfType(IShare::TYPE_USER), $shareOfType(IShare::TYPE_USER)], + IShare::TYPE_LINK => [$shareOfType(IShare::TYPE_LINK)], + default => [], + }); + $this->shareManager->method('getSharedWith')->willReturn([]); + + $propFind = new \Sabre\DAV\PropFind( + '/dummyPath', + [self::SHARETYPES_PROPERTYNAME], + 0 + ); + + $this->plugin->handleGetProperties( + $propFind, + $sabreNode + ); + + $result = $propFind->getResultForMultiStatus(); + $this->assertSame([IShare::TYPE_USER, IShare::TYPE_LINK], $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes()); + } + public static function sharesGetPropertiesDataProvider(): array { return [ [[]],