diff --git a/lib/private/OCM/Model/OCMProvider.php b/lib/private/OCM/Model/OCMProvider.php index 6c1591013a7a3..899cb73aea415 100644 --- a/lib/private/OCM/Model/OCMProvider.php +++ b/lib/private/OCM/Model/OCMProvider.php @@ -179,6 +179,21 @@ public function createNewResourceType(): IOCMResource { */ #[\Override] public function addResourceType(IOCMResource $resource): static { + foreach ($this->resourceTypes as $existing) { + if ($existing->getName() === $resource->getName()) { + $existing->setShareTypes(array_values(array_unique( + array_merge( + $existing->getShareTypes(), + $resource->getShareTypes() + ) + ))); + $existing->setProtocols(array_merge( + $existing->getProtocols(), + $resource->getProtocols() + )); + return $this; + } + } $this->resourceTypes[] = $resource; return $this; diff --git a/tests/lib/OCM/OCMProviderTest.php b/tests/lib/OCM/OCMProviderTest.php new file mode 100644 index 0000000000000..bae2abef9a8b4 --- /dev/null +++ b/tests/lib/OCM/OCMProviderTest.php @@ -0,0 +1,72 @@ +provider = new OCMProvider(); + } + + private function resource(string $name, array $shareTypes, array $protocols): IOCMResource { + $resource = $this->provider->createNewResourceType(); + $resource->setName($name) + ->setShareTypes($shareTypes) + ->setProtocols($protocols); + return $resource; + } + + public function testAddResourceTypeKeepsDistinctNames(): void { + $this->provider->addResourceType($this->resource('file', ['user'], ['webdav' => '/dav/'])); + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []])); + + $this->assertCount(2, $this->provider->getResourceTypes()); + } + + public function testAddResourceTypeMergesSameName(): void { + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []])); + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp-receive' => ['targets' => ['blank', 'iframe']]])); + + $resourceTypes = $this->provider->getResourceTypes(); + $this->assertCount(1, $resourceTypes); + $this->assertSame( + ['webapp' => [], 'webapp-receive' => ['targets' => ['blank', 'iframe']]], + $resourceTypes[0]->getProtocols(), + ); + } + + public function testAddResourceTypeDedupesShareTypes(): void { + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => []])); + $this->provider->addResourceType($this->resource('folder', ['user', 'group'], ['webapp-receive' => []])); + + $shareTypes = $this->provider->getResourceTypes()[0]->getShareTypes(); + $this->assertSame(['user', 'group'], $shareTypes); + // Deduplication must not leave key gaps, or shareTypes would + // serialize as a JSON object instead of an array. + $this->assertSame('["user","group"]', json_encode($shareTypes)); + } + + public function testAddResourceTypeMergeOverwritesSameProtocol(): void { + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => ['a' => 1]])); + $this->provider->addResourceType($this->resource('folder', ['user'], ['webapp' => ['b' => 2]])); + + $this->assertSame( + ['webapp' => ['b' => 2]], + $this->provider->getResourceTypes()[0]->getProtocols(), + ); + } +}