Skip to content

Commit e257c38

Browse files
authored
Merge pull request #56 from microsoftgraph/dev
Release 2.0.0-RC3
2 parents be6fbcc + 5122761 commit e257c38

File tree

6 files changed

+91
-31
lines changed

6 files changed

+91
-31
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ To install the `microsoft-graph-core` library with Composer, either run `compose
77
```
88
{
99
"require": {
10-
"microsoft/microsoft-graph-core": "^2.0.0-RC2"
10+
"microsoft/microsoft-graph-core": "^2.0.0-RC3"
1111
}
1212
}
1313
```

src/Core/GraphConstants.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ final class GraphConstants
2525
const REST_ENDPOINT = "https://graph.microsoft.com/";
2626

2727
// Define HTTP request constants
28-
const SDK_VERSION = "2.0.0-RC2";
28+
const SDK_VERSION = "2.0.0-RC3";
2929

3030
// Define error constants
3131
const MAX_PAGE_SIZE = 999;

src/Exception/GraphResponseException.php

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace Microsoft\Graph\Exception;
1010

1111
use Microsoft\Graph\Http\GraphRequest;
12+
use Psr\Http\Message\StreamInterface;
1213

1314
/**
1415
* Class GraphServiceException
@@ -35,11 +36,17 @@ class GraphResponseException extends \Exception
3536
*/
3637
private $responseStatusCode;
3738
/**
38-
* JSON-decoded response body
39+
* Raw response body
3940
*
40-
* @var array
41+
* @var StreamInterface
4142
*/
42-
private $responseBody;
43+
private $responseStream;
44+
/**
45+
* JSON_decoded response body
46+
*
47+
* @var array|null
48+
*/
49+
private $jsonBody;
4350
/**
4451
* The request that triggered the error response
4552
*
@@ -52,20 +59,21 @@ class GraphResponseException extends \Exception
5259
* GraphServiceException constructor.
5360
* @param GraphRequest $graphRequest
5461
* @param int $responseStatusCode
55-
* @param array $responseBody
62+
* @param StreamInterface $responseStream
5663
* @param array $responseHeaders
5764
*/
5865
public function __construct(
59-
GraphRequest $graphRequest,
60-
int $responseStatusCode,
61-
array $responseBody,
62-
array $responseHeaders
66+
GraphRequest $graphRequest,
67+
int $responseStatusCode,
68+
StreamInterface $responseStream,
69+
array $responseHeaders
6370
) {
6471
$this->graphRequest = $graphRequest;
6572
$this->responseStatusCode = $responseStatusCode;
66-
$this->responseBody = $responseBody;
73+
$this->responseStream = $responseStream;
74+
$this->setJsonBody();
6775
$this->responseHeaders = $responseHeaders;
68-
$message = "'".$graphRequest->getRequestType()."' request to ".$graphRequest->getRequestUri()." returned ".$responseStatusCode."\n".json_encode($responseBody);
76+
$message = "'".$graphRequest->getRequestType()."' request to ".$graphRequest->getRequestUri()." returned ".$responseStatusCode;
6977
parent::__construct($message, $responseStatusCode);
7078
}
7179

@@ -88,12 +96,33 @@ public function getResponseStatusCode(): int {
8896
}
8997

9098
/**
91-
* Get JSON-decoded response payload from the Graph
99+
* Returns the raw response stream
100+
*
101+
* @return StreamInterface
102+
*/
103+
public function getRawResponseBody(): StreamInterface {
104+
return $this->responseStream;
105+
}
106+
107+
/**
108+
* Get the response stream contents as a string
92109
*
93-
* @return array
110+
* @return string
111+
* @throws \RuntimeException if the stream couldn't be read/rewind() failed
94112
*/
95-
public function getRawResponseBody(): array {
96-
return $this->responseBody;
113+
public function getResponseBodyAsString(): string {
114+
$this->responseStream->rewind();
115+
return $this->responseStream->getContents();
116+
}
117+
118+
/**
119+
* Returns the JSON-decoded response payload from the Graph
120+
* If payload could not be JSON-decoded null is returned. Consider getResponseBodyAsString() or getRawResponseBody()
121+
*
122+
* @return array|null
123+
*/
124+
public function getResponseBodyJson(): ?array {
125+
return $this->jsonBody;
97126
}
98127

99128
/**
@@ -102,8 +131,8 @@ public function getRawResponseBody(): array {
102131
* @return ODataErrorContent|null
103132
*/
104133
public function getError(): ?ODataErrorContent {
105-
if (array_key_exists("error", $this->responseBody)) {
106-
return new ODataErrorContent($this->responseBody["error"]);
134+
if (is_array($this->jsonBody) && array_key_exists("error", $this->jsonBody)) {
135+
return new ODataErrorContent($this->jsonBody["error"]);
107136
}
108137
return null;
109138
}
@@ -144,4 +173,16 @@ public function getRequestId(): ?string {
144173
}
145174
return null;
146175
}
176+
177+
/**
178+
* Reads the entire stream's contents and decodes the string
179+
*/
180+
private function setJsonBody(): void {
181+
$this->responseStream->rewind();
182+
try {
183+
$this->jsonBody = json_decode($this->responseStream->getContents(), true);
184+
} catch (\RuntimeException $ex) {
185+
$this->jsonBody = null;
186+
}
187+
}
147188
}

src/Http/GraphRequest.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ class GraphRequest
9999
*/
100100
public function __construct(string $requestType, string $endpoint, AbstractGraphClient $graphClient, string $baseUrl = "")
101101
{
102-
if (!$requestType || !$endpoint || !$graphClient) {
103-
throw new \InvalidArgumentException("Request type, endpoint and client cannot be null or empty");
102+
if (!$requestType || !$endpoint) {
103+
throw new \InvalidArgumentException("Request type and endpoint cannot be null or empty");
104104
}
105105
if (!$graphClient->getAccessToken()) {
106106
throw new \InvalidArgumentException(GraphConstants::NO_ACCESS_TOKEN);
@@ -175,16 +175,15 @@ public function setReturnType(string $returnClass): self
175175
}
176176

177177
/**
178-
* Adds custom headers to the request
178+
* Adds custom headers to the request. Overwrites existing header names
179179
*
180180
* @param array<string, string|string[]> $headers An array of custom headers
181181
*
182182
* @return GraphRequest object
183183
*/
184184
public function addHeaders(array $headers): self
185185
{
186-
// Recursive merge to support appending values to multi-value headers
187-
$this->headers = array_merge_recursive($this->headers, $headers);
186+
$this->headers = array_merge($this->headers, $headers);
188187
$this->initPsr7HttpRequest();
189188
return $this;
190189
}
@@ -439,15 +438,15 @@ private function handleErrorResponse(Response $httpResponse) {
439438
throw new GraphServiceException(
440439
$this,
441440
$httpResponse->getStatusCode(),
442-
json_decode($httpResponse->getBody(), true),
441+
$httpResponse->getBody(),
443442
$httpResponse->getHeaders()
444443
);
445444
}
446445
if ($this->is4xx($httpResponse->getStatusCode())) {
447446
throw new GraphClientException(
448447
$this,
449448
$httpResponse->getStatusCode(),
450-
json_decode($httpResponse->getBody(), true),
449+
$httpResponse->getBody(),
451450
$httpResponse->getHeaders()
452451
);
453452
}

tests/Exception/GraphResponseExceptionTest.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@
1010

1111

1212
use GuzzleHttp\Psr7\Response;
13+
use GuzzleHttp\Psr7\Utils;
1314
use Microsoft\Graph\Exception\GraphResponseException;
1415
use Microsoft\Graph\Exception\ODataErrorContent;
1516
use Microsoft\Graph\Http\GraphRequest;
1617
use Microsoft\Graph\Test\Http\SampleGraphResponsePayload;
18+
use Psr\Http\Message\StreamInterface;
1719

1820
class GraphResponseExceptionTest extends \PHPUnit\Framework\TestCase
1921
{
2022
private $mockGraphRequest;
2123
private $responseStatusCode = 404;
22-
private $responseBody = SampleGraphResponsePayload::ERROR_PAYLOAD;
24+
private $responseBody;
2325
private $responseHeaders = [
2426
"Content-Type" => "application/json",
2527
"request-id" => "2f91ee0a-e013-425b-a5bf-b1f251163969",
@@ -29,12 +31,13 @@ class GraphResponseExceptionTest extends \PHPUnit\Framework\TestCase
2931
private $psr7Response;
3032

3133
protected function setUp(): void {
34+
$this->responseBody = Utils::streamFor(json_encode(SampleGraphResponsePayload::ERROR_PAYLOAD));
3235
$this->mockGraphRequest = $this->createMock(GraphRequest::class);
33-
$this->psr7Response = new Response($this->responseStatusCode, $this->responseHeaders, json_encode($this->responseBody));
36+
$this->psr7Response = new Response($this->responseStatusCode, $this->responseHeaders, $this->responseBody);
3437
$this->defaultException = new GraphResponseException(
3538
$this->mockGraphRequest,
3639
$this->psr7Response->getStatusCode(),
37-
json_decode($this->psr7Response->getBody(), true),
40+
$this->psr7Response->getBody(),
3841
$this->psr7Response->getHeaders()
3942
);
4043
}
@@ -46,11 +49,28 @@ public function testGraphResponseExceptionIsThrowable(): void {
4649
public function testGetters(): void {
4750
$this->assertEquals($this->mockGraphRequest, $this->defaultException->getRequest());
4851
$this->assertEquals($this->responseStatusCode, $this->defaultException->getResponseStatusCode());
49-
$this->assertEquals($this->responseBody, $this->defaultException->getRawResponseBody());
52+
$this->assertInstanceOf(StreamInterface::class, $this->defaultException->getRawResponseBody());
53+
$this->assertEquals(SampleGraphResponsePayload::ERROR_PAYLOAD, $this->defaultException->getResponseBodyJson());
54+
$this->assertEquals(json_encode(SampleGraphResponsePayload::ERROR_PAYLOAD), $this->defaultException->getResponseBodyAsString());
5055
$this->assertEquals($this->psr7Response->getHeaders(), $this->defaultException->getResponseHeaders());
5156
$this->assertInstanceOf(ODataErrorContent::class, $this->defaultException->getError());
5257
}
5358

59+
public function testGettersWithStringResponsePayload(): void {
60+
$responseBody = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request - Invalid Header</h2> <hr><p>HTTP Error 400. The request has an invalid header name.</p> </BODY></HTML>';
61+
$responseException = new GraphResponseException(
62+
$this->mockGraphRequest,
63+
$this->psr7Response->getStatusCode(),
64+
Utils::streamFor($responseBody),
65+
$this->psr7Response->getHeaders()
66+
);
67+
68+
$this->assertInstanceOf(StreamInterface::class, $responseException->getRawResponseBody());
69+
$this->assertNull($responseException->getResponseBodyJson());
70+
$this->assertEquals($responseBody, $responseException->getResponseBodyAsString());
71+
72+
}
73+
5474
public function testGetClientRequestId(): void {
5575
$headerName = "client-request-id";
5676
$this->assertEquals(

tests/Http/Request/GraphRequestTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ public function testAddHeadersWithArrayOfValuesAppendsNewHeaders(): void {
185185
$this->assertEquals($values, $this->defaultGraphRequest->getHeaders()['Accept-Language']);
186186
}
187187

188-
public function testAddHeadersWithExistingHeaderNameDoesCaseSensitiveAppend(): void {
188+
public function testAddHeadersWithExistingHeaderNameOverwrites(): void {
189189
$this->assertEquals('application/json', $this->defaultGraphRequest->getHeaders()['Content-Type']);
190190
$this->defaultGraphRequest->addHeaders(['Content-Type' => 'text']);
191-
$this->assertEquals(["application/json", "text"], $this->defaultGraphRequest->getHeaders()['Content-Type']);
191+
$this->assertEquals("text", $this->defaultGraphRequest->getHeaders()['Content-Type']);
192192
}
193193

194194
public function testAttachBodyReturnsGraphRequestInstance(): void {

0 commit comments

Comments
 (0)