You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
582 lines
19 KiB
582 lines
19 KiB
1 year ago
|
<?php
|
||
|
namespace GuzzleHttp\Tests\Command\Guzzle\ResponseLocation;
|
||
|
|
||
|
use GuzzleHttp\Client;
|
||
|
use GuzzleHttp\Command\Guzzle\Description;
|
||
|
use GuzzleHttp\Command\Guzzle\GuzzleClient;
|
||
|
use GuzzleHttp\Command\Guzzle\Parameter;
|
||
|
use GuzzleHttp\Command\Guzzle\ResponseLocation\JsonLocation;
|
||
|
use GuzzleHttp\Command\Result;
|
||
|
use GuzzleHttp\Command\ResultInterface;
|
||
|
use GuzzleHttp\Handler\MockHandler;
|
||
|
use GuzzleHttp\Psr7\Response;
|
||
|
|
||
|
/**
|
||
|
* @covers \GuzzleHttp\Command\Guzzle\ResponseLocation\JsonLocation
|
||
|
* @covers \GuzzleHttp\Command\Guzzle\Deserializer
|
||
|
*/
|
||
|
class JsonLocationTest extends \PHPUnit_Framework_TestCase
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsLocation()
|
||
|
{
|
||
|
$location = new JsonLocation();
|
||
|
$parameter = new Parameter([
|
||
|
'name' => 'val',
|
||
|
'sentAs' => 'vim',
|
||
|
'filters' => ['strtoupper']
|
||
|
]);
|
||
|
$response = new Response(200, [], '{"vim":"bar"}');
|
||
|
$result = new Result();
|
||
|
$result = $location->before($result, $response, $parameter);
|
||
|
$result = $location->visit($result, $response, $parameter);
|
||
|
$this->assertEquals('BAR', $result['val']);
|
||
|
}
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
* @param $name
|
||
|
* @param $expected
|
||
|
*/
|
||
|
public function testVisitsWiredArray()
|
||
|
{
|
||
|
$json = ['car_models' => ['ferrari', 'aston martin']];
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$guzzle = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description([
|
||
|
'operations' => [
|
||
|
'getCars' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'Cars'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'Cars' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'cars' => [
|
||
|
'type' => 'array',
|
||
|
'sentAs' => 'car_models',
|
||
|
'items' => [
|
||
|
'type' => 'object',
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
|
||
|
$guzzle = new GuzzleClient($guzzle, $description);
|
||
|
$result = $guzzle->getCars();
|
||
|
|
||
|
$this->assertEquals(['cars' => ['ferrari', 'aston martin']], $result->toArray());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsAdditionalProperties()
|
||
|
{
|
||
|
$location = new JsonLocation();
|
||
|
$parameter = new Parameter();
|
||
|
$model = new Parameter(['additionalProperties' => ['location' => 'json']]);
|
||
|
$response = new Response(200, [], '{"vim":"bar","qux":[1,2]}');
|
||
|
$result = new Result();
|
||
|
$result = $location->before($result, $response, $parameter);
|
||
|
$result = $location->visit($result, $response, $parameter);
|
||
|
$result = $location->after($result, $response, $model);
|
||
|
$this->assertEquals('bar', $result['vim']);
|
||
|
$this->assertEquals([1, 2], $result['qux']);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsAdditionalPropertiesWithEmptyResponse()
|
||
|
{
|
||
|
$location = new JsonLocation();
|
||
|
$parameter = new Parameter();
|
||
|
$model = new Parameter(['additionalProperties' => ['location' => 'json']]);
|
||
|
$response = new Response(204);
|
||
|
$result = new Result();
|
||
|
$result = $location->before($result, $response, $parameter);
|
||
|
$result = $location->visit($result, $response, $parameter);
|
||
|
$result = $location->after($result, $response, $model);
|
||
|
$this->assertEquals([], $result->toArray());
|
||
|
}
|
||
|
|
||
|
public function jsonProvider()
|
||
|
{
|
||
|
return [
|
||
|
[null, [['foo' => 'BAR'], ['baz' => 'BAM']]],
|
||
|
['under_me', ['under_me' => [['foo' => 'BAR'], ['baz' => 'BAM']]]],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider jsonProvider
|
||
|
* @group ResponseLocation
|
||
|
* @param $name
|
||
|
* @param $expected
|
||
|
*/
|
||
|
public function testVisitsTopLevelArrays($name, $expected)
|
||
|
{
|
||
|
$json = [
|
||
|
['foo' => 'bar'],
|
||
|
['baz' => 'bam'],
|
||
|
];
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$guzzle = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description([
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'array',
|
||
|
'location' => 'json',
|
||
|
'name' => $name,
|
||
|
'items' => [
|
||
|
'type' => 'object',
|
||
|
'additionalProperties' => [
|
||
|
'type' => 'string',
|
||
|
'filters' => ['strtoupper']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
$guzzle = new GuzzleClient($guzzle, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsNestedArrays()
|
||
|
{
|
||
|
$json = [
|
||
|
'scalar' => 'foo',
|
||
|
'nested' => [
|
||
|
'bar',
|
||
|
'baz'
|
||
|
]
|
||
|
];
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$httpClient = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description([
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'scalar' => ['type' => 'string'],
|
||
|
'nested' => [
|
||
|
'type' => 'array',
|
||
|
'items' => ['type' => 'string']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
$guzzle = new GuzzleClient($httpClient, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
$expected = [
|
||
|
'scalar' => 'foo',
|
||
|
'nested' => [
|
||
|
'bar',
|
||
|
'baz'
|
||
|
]
|
||
|
];
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
|
||
|
public function nestedProvider()
|
||
|
{
|
||
|
return [
|
||
|
[
|
||
|
[
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'nested' => [
|
||
|
'location' => 'json',
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'foo' => ['type' => 'string'],
|
||
|
'bar' => ['type' => 'number'],
|
||
|
'bam' => [
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'abc' => [
|
||
|
'type' => 'number'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'additionalProperties' => [
|
||
|
'location' => 'json',
|
||
|
'type' => 'string',
|
||
|
'filters' => ['strtoupper']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'nested' => [
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'foo' => ['type' => 'string'],
|
||
|
'bar' => ['type' => 'number'],
|
||
|
'bam' => [
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'abc' => [
|
||
|
'type' => 'number'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
'additionalProperties' => [
|
||
|
'type' => 'string',
|
||
|
'filters' => ['strtoupper']
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dataProvider nestedProvider
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsNestedProperties($desc)
|
||
|
{
|
||
|
$json = [
|
||
|
'nested' => [
|
||
|
'foo' => 'abc',
|
||
|
'bar' => 123,
|
||
|
'bam' => [
|
||
|
'abc' => 456
|
||
|
]
|
||
|
],
|
||
|
'baz' => 'boo'
|
||
|
];
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$httpClient = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description($desc);
|
||
|
$guzzle = new GuzzleClient($httpClient, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
$expected = [
|
||
|
'nested' => [
|
||
|
'foo' => 'abc',
|
||
|
'bar' => 123,
|
||
|
'bam' => [
|
||
|
'abc' => 456
|
||
|
]
|
||
|
],
|
||
|
'baz' => 'BOO'
|
||
|
];
|
||
|
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsNullResponseProperties()
|
||
|
{
|
||
|
|
||
|
$json = [
|
||
|
'data' => [
|
||
|
'link' => null
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$httpClient = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description(
|
||
|
[
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'scalar' => ['type' => 'string'],
|
||
|
'data' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'link' => [
|
||
|
'name' => 'val',
|
||
|
'type' => 'string',
|
||
|
'location' => 'json'
|
||
|
],
|
||
|
],
|
||
|
'additionalProperties' => false
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
);
|
||
|
$guzzle = new GuzzleClient($httpClient, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
|
||
|
$expected = [
|
||
|
'data' => [
|
||
|
'link' => null
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsNestedArrayOfArrays()
|
||
|
{
|
||
|
$json = [
|
||
|
'scalar' => 'foo',
|
||
|
'nested' => [
|
||
|
[
|
||
|
'bar' => 123,
|
||
|
'baz' => false,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 345,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 678,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$httpClient = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description([
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'scalar' => [
|
||
|
// for some reason (probably because location is also set on array of arrays)
|
||
|
// array of arrays sibling elements must have location set to `json`
|
||
|
// otherwise JsonLocation ignores them
|
||
|
'location' => 'json',
|
||
|
'type' => 'string'
|
||
|
],
|
||
|
'nested' => [
|
||
|
// array of arrays type must be set to `array`
|
||
|
// without that JsonLocation throws an exception
|
||
|
'type' => 'array',
|
||
|
// for array of arrays `location` must be set to `json`
|
||
|
// otherwise JsonLocation returns an empty array
|
||
|
'location' => 'json',
|
||
|
'items' => [
|
||
|
// although this is array of arrays, array items type
|
||
|
// must be set as `object`
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'bar' => [
|
||
|
'type' => 'integer',
|
||
|
],
|
||
|
'baz' => [
|
||
|
'type' => 'boolean',
|
||
|
],
|
||
|
],
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
|
||
|
$guzzle = new GuzzleClient($httpClient, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
$expected = [
|
||
|
'scalar' => 'foo',
|
||
|
'nested' => [
|
||
|
[
|
||
|
'bar' => 123,
|
||
|
'baz' => false,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 345,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 678,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @group ResponseLocation
|
||
|
*/
|
||
|
public function testVisitsNestedArrayOfObjects()
|
||
|
{
|
||
|
$json = json_decode('{"scalar":"foo","nested":[{"bar":123,"baz":false},{"bar":345,"baz":true},{"bar":678,"baz":true}]}');
|
||
|
|
||
|
$body = \GuzzleHttp\json_encode($json);
|
||
|
$response = new Response(200, ['Content-Type' => 'application/json'], $body);
|
||
|
$mock = new MockHandler([$response]);
|
||
|
|
||
|
$httpClient = new Client(['handler' => $mock]);
|
||
|
|
||
|
$description = new Description([
|
||
|
'operations' => [
|
||
|
'foo' => [
|
||
|
'uri' => 'http://httpbin.org',
|
||
|
'httpMethod' => 'GET',
|
||
|
'responseModel' => 'j'
|
||
|
]
|
||
|
],
|
||
|
'models' => [
|
||
|
'j' => [
|
||
|
'type' => 'object',
|
||
|
'location' => 'json',
|
||
|
'properties' => [
|
||
|
'scalar' => [
|
||
|
'type' => 'string'
|
||
|
],
|
||
|
'nested' => [
|
||
|
// array of objects type must be set to `array`
|
||
|
// without that JsonLocation throws an exception
|
||
|
'type' => 'array',
|
||
|
'items' => [
|
||
|
// array elements type must be set to `object`
|
||
|
'type' => 'object',
|
||
|
'properties' => [
|
||
|
'bar' => [
|
||
|
'type' => 'integer',
|
||
|
],
|
||
|
'baz' => [
|
||
|
'type' => 'boolean',
|
||
|
],
|
||
|
],
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
|
||
|
$guzzle = new GuzzleClient($httpClient, $description);
|
||
|
/** @var ResultInterface $result */
|
||
|
$result = $guzzle->foo();
|
||
|
$expected = [
|
||
|
'scalar' => 'foo',
|
||
|
'nested' => [
|
||
|
[
|
||
|
'bar' => 123,
|
||
|
'baz' => false,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 345,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
[
|
||
|
'bar' => 678,
|
||
|
'baz' => true,
|
||
|
],
|
||
|
]
|
||
|
];
|
||
|
$this->assertEquals($expected, $result->toArray());
|
||
|
}
|
||
|
}
|