diff --git a/.drone.env b/.drone.env index 6fbb11e1..074764a8 100644 --- a/.drone.env +++ b/.drone.env @@ -1,5 +1,5 @@ # The version of OCIS to use in pipelines that test against OCIS -OCIS_COMMITID=c18d71788351ac878d2016b178e3e87c673e62a3 +OCIS_COMMITID=aa6041abb6e8094306216fbe354403df14b47c70 OCIS_BRANCH=master -OCIS_STABLE_COMMITID=48ab941943a9eb3b510b7029ba39ba445a6aac1b +OCIS_STABLE_COMMITID=214491134f5674ac735635ea259969663d9ad4c7 OCIS_STABLE_BRANCH=stable-5.0 diff --git a/src/Drive.php b/src/Drive.php index 59ff3e17..c9bf9777 100644 --- a/src/Drive.php +++ b/src/Drive.php @@ -14,6 +14,7 @@ use OpenAPI\Client\Model\OdataError; use OpenAPI\Client\Model\Quota; use Owncloud\OcisPhpSdk\Exception\BadRequestException; +use Owncloud\OcisPhpSdk\Exception\EndPointNotImplementedException; use Owncloud\OcisPhpSdk\Exception\ExceptionHelper; use Owncloud\OcisPhpSdk\Exception\ForbiddenException; use Owncloud\OcisPhpSdk\Exception\HttpException; @@ -42,6 +43,7 @@ class Drive private array $connectionConfig; private Configuration $graphApiConfig; private string $serviceUrl; + private string $ocisVersion; /** * @ignore The developer using the SDK does not need to create drives manually, but should use the Ocis class @@ -53,11 +55,13 @@ public function __construct( ApiDrive $apiDrive, array $connectionConfig, string $serviceUrl, - string &$accessToken + string &$accessToken, + string $ocisVersion ) { $this->apiDrive = $apiDrive; $this->accessToken = &$accessToken; $this->serviceUrl = $serviceUrl; + $this->ocisVersion = $ocisVersion; if (!Ocis::isConnectionConfigValid($connectionConfig)) { throw new \InvalidArgumentException('connection configuration not valid'); } @@ -583,9 +587,13 @@ public function emptyTrashbin(): bool * @throws UnauthorizedException * @throws InvalidResponseException * @throws InternalServerErrorException + * @throws EndPointNotImplementedException */ public function getRoles(): array { + if((version_compare($this->ocisVersion, '6.0.0', '<'))) { + throw new EndPointNotImplementedException(Ocis::ENDPOINT_NOT_IMPLEMENTED_ERROR_MESSAGE); + }; $guzzle = new Client( Ocis::createGuzzleConfig($this->connectionConfig, $this->accessToken) ); diff --git a/src/Exception/EndPointNotImplementedException.php b/src/Exception/EndPointNotImplementedException.php new file mode 100644 index 00000000..c6da63b8 --- /dev/null +++ b/src/Exception/EndPointNotImplementedException.php @@ -0,0 +1,10 @@ +graphApiConfig = Configuration::getDefaultConfiguration()->setHost( $this->serviceUrl . '/graph' ); - } public function getServiceUrl(): string @@ -306,6 +308,33 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string } throw new InvalidResponseException('invalid webfinger response'); } + + /** + * returns the current oCIS version in semantic versioning format ( e.g. "5.0.5" ) + * + * @return string + * @throws InvalidResponseException + */ + public function getOcisVersion(): string + { + if(($this->ocisVersion)) { + return $this->ocisVersion; + } else { + $response = $this->guzzle->get($this->serviceUrl . '/ocs/v1.php/cloud/capabilities'); + $responseContent = $response->getBody()->getContents(); + + $body = simplexml_load_string($responseContent); + if (!isset($body->data->version->productversion)) { + throw new InvalidResponseException('Missing productversion element in XML response'); + } + $version = (string)$body->data->version->productversion; + $pattern = '(\d\.\d\.\d)'; + preg_match($pattern, $version, $matches); + $this->ocisVersion = $matches[0]; + return $this->ocisVersion; + } + } + /** * Get all available drives * @@ -358,7 +387,8 @@ public function getAllDrives( $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->getOcisVersion() ); $drives[] = $drive; } @@ -415,7 +445,8 @@ public function getMyDrives( $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->getOcisVersion() ); $drives[] = $drive; } @@ -472,7 +503,8 @@ public function getDriveById(string $driveId): Drive $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->getOcisVersion() ); } @@ -524,7 +556,8 @@ public function createDrive( $newlyCreatedDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->getOcisVersion() ); } throw new InvalidResponseException( diff --git a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php index 97d2f52f..e0c7686e 100644 --- a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php +++ b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php @@ -4,6 +4,7 @@ use Owncloud\OcisPhpSdk\Drive; use Owncloud\OcisPhpSdk\Exception\BadRequestException; +use Owncloud\OcisPhpSdk\Exception\EndPointNotImplementedException; use Owncloud\OcisPhpSdk\Exception\NotFoundException; use Owncloud\OcisPhpSdk\Ocis; use Owncloud\OcisPhpSdk\SharingRole; @@ -72,19 +73,22 @@ public function testDeleteEnabledDrive(): void public function testGetDriveRole(): void { - // At the time of writing, "stable" is major version 5 of ocis. - // This functionality works with major version 6. - // When ocis major version 6 has been released as "stable" then remove this test skip. + //ocis stable doesn't support root endpoint if (getenv('OCIS_VERSION') === "stable") { - $this->markTestSkipped( - 'This test is skipped because root endpoint for drive share is not applicable for version 5 of OCIS.' + $this->expectException(EndPointNotImplementedException::class); + $this->expectExceptionMessage("This method is not implemented in this ocis version"); + $this->drive->getRoles(); + } + try { + $role = $this->drive->getRoles(); + $this->assertContainsOnlyInstancesOf( + SharingRole::class, + $role, + "Array contains not only 'SharingRole' items" ); + } catch(EndPointNotImplementedException) { + //test should fail if ocis version is less than 6.0.0 + $this->fail("EndPointNotImplementedException was thrown unexpectedly"); }; - $role = $this->drive->getRoles(); - $this->assertContainsOnlyInstancesOf( - SharingRole::class, - $role, - "Array contains not only 'SharingRole' items" - ); } } diff --git a/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php b/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php index d52d0f50..8a4e98cd 100644 --- a/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php +++ b/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php @@ -14,6 +14,7 @@ use Owncloud\OcisPhpSdk\Exception\HttpException; use Owncloud\OcisPhpSdk\Exception\InvalidResponseException; use Owncloud\OcisPhpSdk\Ocis; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; @@ -121,7 +122,8 @@ public function testSetAccessTokenPropagatesToDrives(): void $ocis = new Ocis( 'https://localhost:9200', 'tokenWhenCreated', - ['drivesGetDrivesApi' => $drivesGetDrivesApi] + /* @phpstan-ignore-next-line */ + [ 'guzzle' => $this->setUpMocksForOcisVersion(), 'drivesGetDrivesApi' => $drivesGetDrivesApi] ); $drives = $ocis->getAllDrives(); foreach ($drives as $drive) { @@ -149,6 +151,29 @@ public function testSetAccessTokenPropagatesToNotifications(): void $this->assertSame('changedToken', $notifications[1]->getAccessToken()); } + private function setUpMocksForOcisVersion(?string $responseContent = null): MockObject + { + if ($responseContent === null) { + $responseContent = << + + + 6.0.0 + + + + XML; + }; + $streamMock = $this->createMock(StreamInterface::class); + $streamMock->method('getContents')->willReturn($responseContent); + $responseMock = $this->createMock(ResponseInterface::class); + $responseMock->method('getBody')->willReturn($streamMock); + $guzzleMock = $this->createMock(Client::class); + $guzzleMock->method('get') + ->willReturn($responseMock); + return $guzzleMock; + } + private function setupMocksForNotificationTests( string $responseContent, string $token = 'doesNotMatter'