Skip to content

Commit

Permalink
Merge pull request #2 from microsoft/fix/url-building
Browse files Browse the repository at this point in the history
Path parameter URL building verification
  • Loading branch information
Ndiritu authored Oct 3, 2022
2 parents 12dfc52 + 80e0b48 commit cb87a9d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 6 deletions.
42 changes: 42 additions & 0 deletions src/RequestInformation.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?php
namespace Microsoft\Kiota\Abstractions;

use DateTime;
use DateTimeInterface;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Exception;
use InvalidArgumentException;
use League\Uri\Contracts\UriException;
use League\Uri\UriTemplate;
use Microsoft\Kiota\Abstractions\Serialization\Parsable;
use Microsoft\Kiota\Abstractions\Types\Date;
use Psr\Http\Message\StreamInterface;
use RuntimeException;

Expand Down Expand Up @@ -62,12 +65,35 @@ public function getUri(): string {
$this->setUri($this->pathParameters[self::$RAW_URL_KEY]);
} else {
$template = new UriTemplate($this->urlTemplate);
if (substr_count(strtolower($this->urlTemplate), '{+baseurl}') > 0 && !isset($this->pathParameters['baseurl'])) {
throw new InvalidArgumentException('"PathParameters must contain a value for "baseurl" for the url to be built.');
}

foreach ($this->pathParameters as $key => $pathParameter) {
$this->pathParameters[$key] = $this->sanitizeValue($pathParameter);
}

foreach ($this->queryParameters as $key => $queryParameter) {
$this->queryParameters[$key] = $this->sanitizeValue($queryParameter);
}
$params = array_merge($this->pathParameters, $this->queryParameters);

return $template->expand($params);
}
return $this->uri;
}

/**
* @param mixed $value
* @return mixed
*/
private function sanitizeValue($value) {
if (is_object($value) && is_a($value, DateTime::class)) {
return $value->format(DateTimeInterface::ATOM);
}
return $value;
}

/**
* Sets the URI of the request.
*/
Expand Down Expand Up @@ -173,4 +199,20 @@ public function setQueryParameters(?object $queryParameters): void {
public function setPathParameters(array $pathParameters): void {
$this->pathParameters = $pathParameters;
}

/**
* Set the headers and update if we already have some headers.
* @param array<string, mixed> $headers
*/
public function setHeaders(array $headers): void {
$this->headers = array_merge($this->headers, $headers);
}

/**
* Get the headers and update if we already have some headers.
* @return array<string, mixed>
*/
public function getHeaders(): array {
return $this->headers;
}
}
80 changes: 74 additions & 6 deletions tests/RequestInformationTest.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<?php

namespace Microsoft\Kiota\Abstractions\Tests;
use DateTime;
use DateTimeZone;
use InvalidArgumentException;
use League\Uri\Contracts\UriException;
use Microsoft\Kiota\Abstractions\HttpMethod;
use Microsoft\Kiota\Abstractions\RequestInformation;
use PHPUnit\Framework\TestCase;
use Microsoft\Kiota\Abstractions\QueryParameter;
use Rize\UriTemplate;

class RequestInformationTest extends TestCase {
private RequestInformation $requestInformation;
Expand All @@ -13,20 +17,26 @@ protected function setUp(): void {
$this->requestInformation = new RequestInformation();
}

/**
* @throws UriException
*/
public function testSetUri(): void{
$pathParameters = [
'baseUrl' => 'https://google.com',
'baseurl' => 'https://google.com',
'user%2Did' => 'silas',
];
$queryParameters = ['%24select' => ['subject', 'importance']];
$this->requestInformation->urlTemplate = '{+baseUrl}/{user%2Did}/mails{?%24select}';
$this->requestInformation->pathParameters = $pathParameters;
$this->requestInformation->urlTemplate = '{+baseurl}/{user%2Did}/mails{?%24select}';
$this->requestInformation->setPathParameters($pathParameters);
$this->requestInformation->queryParameters = $queryParameters;
$this->assertEquals("https://google.com/silas/mails?%24select=subject,importance", $this->requestInformation->getUri());
}

/**
* @throws UriException
*/
public function testSetQueryParameters(): void {
$this->requestInformation->urlTemplate = '{?%24select,top}';
$this->requestInformation->urlTemplate = '{?%24select,top,%24count}';

$queryParam = new TestQueryParameter();
$this->requestInformation->setQueryParameters($queryParam);
Expand All @@ -40,12 +50,70 @@ public function testSetQueryParameters(): void {
$this->assertArrayHasKey('top', $this->requestInformation->queryParameters);
$this->assertEquals('?%24select=displayName,age&top=10', $this->requestInformation->getUri());
}

/**
* @throws UriException
*/
public function testWillThrowExceptionWhenNoBaseUrl(): void {
$this->expectException(InvalidArgumentException::class);
$pathParameters = [
'bad' => 'https://google.com',
'user%2Did' => 'silas',
];
$this->requestInformation->urlTemplate = '{+baseurl}/{user%2Did}/mails{?%24select}';
$this->requestInformation->setPathParameters($pathParameters);
$uri = $this->requestInformation->getUri();
$this->assertEquals('', $uri);
}

/**
* @throws UriException
*/
public function testPathParametersOfDateTimeOffsetType(): void
{
// Arrange as the request builders would
$requestInfo = new RequestInformation();
$requestInfo->httpMethod = HttpMethod::GET;
$requestInfo->urlTemplate = "https://localhost/getDirectRoutingCalls(fromDateTime='{fromDateTime}',toDateTime='{toDateTime}')";

// Act
$fromDateTime =new DateTime();
$fromDateTime->setDate(2022, 8, 1);
$fromDateTime->setTime(0,0);
$fromDateTime->setTimezone(new DateTimeZone('+00:00'));
$toDateTime =new DateTime();
$toDateTime->setDate(2022, 8, 2);
$toDateTime->setTime(0,0);
$toDateTime->setTimezone(new DateTimeZone('+00:00'));
$requestInfo->pathParameters["fromDateTime"] = $fromDateTime;
$requestInfo->pathParameters["toDateTime"] = $toDateTime;

// Assert
$uri = $requestInfo->getUri();
$this->assertEquals("https://localhost/getDirectRoutingCalls(fromDateTime='2022-08-01T00%3A00%3A00%2B00%3A00',toDateTime='2022-08-02T00%3A00%3A00%2B00%3A00')", $uri);
}

/**
* @throws UriException
*/
public function testCanHandleBooleanTypes(): void {
// Arrange as the request builders would
$requestInfo = new RequestInformation();
$requestInfo->httpMethod = HttpMethod::GET;
$requestInfo->urlTemplate = "http://localhost/users{?%24count}";

$requestInfo->setPathParameters(['%24count' => true]);
// Assert
$uri = $requestInfo->getUri();
$this->assertEquals('http://localhost/users?%24count=1', $uri);
}
}

class TestQueryParameter {
/**
* @QueryParameter("%24select")
*/
public ?array $select = null;
public bool $count = false;
public int $top = 10; // no annotation
}
}

0 comments on commit cb87a9d

Please sign in to comment.