2013-01-10 15:28:59 -06:00
|
|
|
<?php
|
|
|
|
|
|
2017-01-17 14:30:19 +00:00
|
|
|
namespace Illuminate\Tests\Http;
|
|
|
|
|
|
2019-02-07 17:04:40 +01:00
|
|
|
use BadMethodCallException;
|
2019-09-10 17:16:05 +02:00
|
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
|
|
|
use Illuminate\Contracts\Support\Jsonable;
|
|
|
|
|
use Illuminate\Contracts\Support\MessageProvider;
|
|
|
|
|
use Illuminate\Contracts\Support\Renderable;
|
|
|
|
|
use Illuminate\Http\RedirectResponse;
|
2013-01-10 15:28:59 -06:00
|
|
|
use Illuminate\Http\Request;
|
2018-10-05 14:48:10 +02:00
|
|
|
use Illuminate\Http\Response;
|
|
|
|
|
use Illuminate\Session\Store;
|
|
|
|
|
use Illuminate\Support\MessageBag;
|
|
|
|
|
use Illuminate\Support\ViewErrorBag;
|
2019-09-10 17:16:05 +02:00
|
|
|
use JsonSerializable;
|
|
|
|
|
use Mockery as m;
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
2018-10-05 14:48:10 +02:00
|
|
|
use Symfony\Component\HttpFoundation\Cookie;
|
|
|
|
|
use Symfony\Component\HttpFoundation\HeaderBag;
|
|
|
|
|
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
2013-01-10 15:28:59 -06:00
|
|
|
|
2016-12-30 21:31:11 +01:00
|
|
|
class HttpResponseTest extends TestCase
|
2015-06-01 16:26:53 +01:00
|
|
|
{
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testJsonResponsesAreConvertedAndHeadersAreSet()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(new ArrayableStub);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo":"bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2017-02-10 15:13:41 +01:00
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(new JsonableStub);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('foo', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2015-06-01 15:56:31 +01:00
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(new ArrayableAndJsonableStub);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo":"bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2017-02-10 15:13:41 +01:00
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response;
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setContent(['foo' => 'bar']);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo":"bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2015-12-20 21:04:47 +01:00
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(new JsonSerializableStub);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo":"bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2015-06-01 15:56:31 +01:00
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(new ArrayableStub);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo":"bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2017-03-13 15:43:30 +01:00
|
|
|
|
2017-07-30 01:06:15 +01:00
|
|
|
$response->setContent('{"foo": "bar"}');
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('{"foo": "bar"}', $response->getContent());
|
|
|
|
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
2017-03-13 15:43:30 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testRenderablesAreRendered()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$mock = m::mock(Renderable::class);
|
2015-06-01 15:56:31 +01:00
|
|
|
$mock->shouldReceive('render')->once()->andReturn('foo');
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response($mock);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('foo', $response->getContent());
|
2015-06-01 15:56:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testHeader()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response;
|
2015-06-01 15:56:31 +01:00
|
|
|
$this->assertNull($response->headers->get('foo'));
|
|
|
|
|
$response->header('foo', 'bar');
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('bar', $response->headers->get('foo'));
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->header('foo', 'baz', false);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('bar', $response->headers->get('foo'));
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->header('foo', 'baz');
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('baz', $response->headers->get('foo'));
|
2015-06-01 15:56:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testWithCookie()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response;
|
2016-03-02 12:38:56 +01:00
|
|
|
$this->assertCount(0, $response->headers->getCookies());
|
2018-10-05 14:48:10 +02:00
|
|
|
$this->assertEquals($response, $response->withCookie(new Cookie('foo', 'bar')));
|
2015-06-01 15:56:31 +01:00
|
|
|
$cookies = $response->headers->getCookies();
|
2016-03-02 12:38:56 +01:00
|
|
|
$this->assertCount(1, $cookies);
|
2019-08-27 14:48:17 +02:00
|
|
|
$this->assertSame('foo', $cookies[0]->getName());
|
|
|
|
|
$this->assertSame('bar', $cookies[0]->getValue());
|
2015-06-01 15:56:31 +01:00
|
|
|
}
|
|
|
|
|
|
2024-08-08 15:30:23 +02:00
|
|
|
public function testResponseCookiesInheritRequestSecureState()
|
|
|
|
|
{
|
|
|
|
|
$cookie = Cookie::create('foo', 'bar');
|
|
|
|
|
|
|
|
|
|
$response = new Response('foo');
|
|
|
|
|
$response->headers->setCookie($cookie);
|
|
|
|
|
|
|
|
|
|
$request = Request::create('/', 'GET');
|
|
|
|
|
$response->prepare($request);
|
|
|
|
|
|
|
|
|
|
$this->assertFalse($cookie->isSecure());
|
|
|
|
|
|
|
|
|
|
$request = Request::create('https://localhost/', 'GET');
|
|
|
|
|
$response->prepare($request);
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($cookie->isSecure());
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testGetOriginalContent()
|
|
|
|
|
{
|
2015-06-01 16:35:44 +01:00
|
|
|
$arr = ['foo' => 'bar'];
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response;
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->setContent($arr);
|
|
|
|
|
$this->assertSame($arr, $response->getOriginalContent());
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-12 14:31:49 +02:00
|
|
|
public function testGetOriginalContentRetrievesTheFirstOriginalContent()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$previousResponse = new Response(['foo' => 'bar']);
|
|
|
|
|
$response = new Response($previousResponse);
|
2017-07-12 14:31:49 +02:00
|
|
|
|
|
|
|
|
$this->assertSame(['foo' => 'bar'], $response->getOriginalContent());
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testSetAndRetrieveStatusCode()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response('foo');
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->setStatusCode(404);
|
|
|
|
|
$this->assertSame(404, $response->getStatusCode());
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-24 07:13:14 -07:00
|
|
|
public function testSetStatusCodeAndRetrieveStatusText()
|
|
|
|
|
{
|
|
|
|
|
$response = new Response('foo');
|
|
|
|
|
$response->setStatusCode(404);
|
|
|
|
|
$this->assertSame('Not Found', $response->statusText());
|
|
|
|
|
}
|
2021-06-24 09:13:42 -05:00
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testOnlyInputOnRedirect()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));
|
2018-10-05 14:48:10 +02:00
|
|
|
$response->setSession($session = m::mock(Store::class));
|
2015-06-01 16:35:44 +01:00
|
|
|
$session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->onlyInput('name');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testExceptInputOnRedirect()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));
|
2018-10-05 14:48:10 +02:00
|
|
|
$response->setSession($session = m::mock(Store::class));
|
2015-06-01 16:35:44 +01:00
|
|
|
$session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->exceptInput('age');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testFlashingErrorsOnRedirect()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));
|
2018-10-05 14:48:10 +02:00
|
|
|
$response->setSession($session = m::mock(Store::class));
|
|
|
|
|
$session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);
|
|
|
|
|
$session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));
|
|
|
|
|
$provider = m::mock(MessageProvider::class);
|
|
|
|
|
$provider->shouldReceive('getMessageBag')->once()->andReturn(new MessageBag);
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->withErrors($provider);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testSettersGettersOnRequest()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
|
|
|
|
$this->assertNull($response->getRequest());
|
|
|
|
|
$this->assertNull($response->getSession());
|
|
|
|
|
|
|
|
|
|
$request = Request::create('/', 'GET');
|
2018-10-05 14:48:10 +02:00
|
|
|
$session = m::mock(Store::class);
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->setRequest($request);
|
|
|
|
|
$response->setSession($session);
|
|
|
|
|
$this->assertSame($request, $response->getRequest());
|
|
|
|
|
$this->assertSame($session, $response->getSession());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testRedirectWithErrorsArrayConvertsToMessageBag()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));
|
2018-10-05 14:48:10 +02:00
|
|
|
$response->setSession($session = m::mock(Store::class));
|
|
|
|
|
$session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);
|
|
|
|
|
$session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));
|
2015-06-01 16:35:44 +01:00
|
|
|
$provider = ['foo' => 'bar'];
|
2015-06-01 15:56:31 +01:00
|
|
|
$response->withErrors($provider);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-28 22:06:52 +01:00
|
|
|
public function testWithHeaders()
|
|
|
|
|
{
|
2018-10-05 14:48:10 +02:00
|
|
|
$response = new Response(null, 200, ['foo' => 'bar']);
|
2017-02-28 22:06:52 +01:00
|
|
|
$this->assertSame('bar', $response->headers->get('foo'));
|
|
|
|
|
|
|
|
|
|
$response->withHeaders(['foo' => 'BAR', 'bar' => 'baz']);
|
|
|
|
|
$this->assertSame('BAR', $response->headers->get('foo'));
|
|
|
|
|
$this->assertSame('baz', $response->headers->get('bar'));
|
|
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$responseMessageBag = new ResponseHeaderBag(['bar' => 'BAZ', 'titi' => 'toto']);
|
2017-02-28 22:06:52 +01:00
|
|
|
$response->withHeaders($responseMessageBag);
|
|
|
|
|
$this->assertSame('BAZ', $response->headers->get('bar'));
|
|
|
|
|
$this->assertSame('toto', $response->headers->get('titi'));
|
|
|
|
|
|
2018-10-05 14:48:10 +02:00
|
|
|
$headerBag = new HeaderBag(['bar' => 'BAAA', 'titi' => 'TATA']);
|
2017-02-28 22:06:52 +01:00
|
|
|
$response->withHeaders($headerBag);
|
|
|
|
|
$this->assertSame('BAAA', $response->headers->get('bar'));
|
|
|
|
|
$this->assertSame('TATA', $response->headers->get('titi'));
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-07 20:33:44 +03:30
|
|
|
public function testWithoutHeader()
|
|
|
|
|
{
|
|
|
|
|
$response = new Response(null, 200, ['foo' => 'bar', 'baz' => 'qux', 'zal' => 'ter']);
|
|
|
|
|
$this->assertSame('bar', $response->headers->get('foo'));
|
|
|
|
|
$this->assertSame('qux', $response->headers->get('baz'));
|
|
|
|
|
$this->assertSame('ter', $response->headers->get('zal'));
|
|
|
|
|
|
|
|
|
|
// Test removing single header
|
|
|
|
|
$result = $response->withoutHeader('foo');
|
|
|
|
|
$this->assertSame($response, $result);
|
|
|
|
|
$this->assertNull($response->headers->get('foo'));
|
|
|
|
|
$this->assertSame('qux', $response->headers->get('baz'));
|
|
|
|
|
$this->assertSame('ter', $response->headers->get('zal'));
|
|
|
|
|
|
|
|
|
|
// Test removing multiple headers at once
|
|
|
|
|
$response->withoutHeader(['baz', 'zal']);
|
|
|
|
|
$this->assertNull($response->headers->get('baz'));
|
|
|
|
|
$this->assertNull($response->headers->get('zal'));
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
public function testMagicCall()
|
|
|
|
|
{
|
|
|
|
|
$response = new RedirectResponse('foo.bar');
|
2015-06-01 16:35:44 +01:00
|
|
|
$response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));
|
2018-10-05 14:48:10 +02:00
|
|
|
$response->setSession($session = m::mock(Store::class));
|
2015-06-01 15:56:31 +01:00
|
|
|
$session->shouldReceive('flash')->once()->with('foo', 'bar');
|
|
|
|
|
$response->withFoo('bar');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testMagicCallException()
|
|
|
|
|
{
|
2019-02-07 17:04:40 +01:00
|
|
|
$this->expectException(BadMethodCallException::class);
|
|
|
|
|
$this->expectExceptionMessage('Call to undefined method Illuminate\Http\RedirectResponse::doesNotExist()');
|
|
|
|
|
|
2015-06-01 15:56:31 +01:00
|
|
|
$response = new RedirectResponse('foo.bar');
|
|
|
|
|
$response->doesNotExist('bar');
|
|
|
|
|
}
|
2013-01-10 15:28:59 -06:00
|
|
|
}
|
|
|
|
|
|
2017-02-10 15:13:41 +01:00
|
|
|
class ArrayableStub implements Arrayable
|
|
|
|
|
{
|
|
|
|
|
public function toArray()
|
|
|
|
|
{
|
|
|
|
|
return ['foo' => 'bar'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ArrayableAndJsonableStub implements Arrayable, Jsonable
|
|
|
|
|
{
|
|
|
|
|
public function toJson($options = 0)
|
|
|
|
|
{
|
|
|
|
|
return '{"foo":"bar"}';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function toArray()
|
|
|
|
|
{
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 16:26:53 +01:00
|
|
|
class JsonableStub implements Jsonable
|
|
|
|
|
{
|
|
|
|
|
public function toJson($options = 0)
|
|
|
|
|
{
|
|
|
|
|
return 'foo';
|
|
|
|
|
}
|
2014-02-27 19:30:59 +00:00
|
|
|
}
|
2015-12-20 21:04:47 +01:00
|
|
|
|
2017-02-10 15:13:41 +01:00
|
|
|
class JsonSerializableStub implements JsonSerializable
|
2015-12-20 21:04:47 +01:00
|
|
|
{
|
2021-06-28 15:56:26 +02:00
|
|
|
public function jsonSerialize(): array
|
2015-12-20 21:04:47 +01:00
|
|
|
{
|
|
|
|
|
return ['foo' => 'bar'];
|
|
|
|
|
}
|
|
|
|
|
}
|