582 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			582 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			PHP
		
	
	
<?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());
 | 
						|
    }
 | 
						|
}
 |