SIGN IN SIGN UP
laravel / framework UNCLAIMED

Laravel is a web application framework with expressive, elegant syntax.

2017-01-31 23:09:17 +02:00
<?php
namespace Illuminate\Tests\Testing;
2017-01-31 23:09:17 +02:00
use Exception;
2020-12-14 15:30:57 -05:00
use Illuminate\Container\Container;
use Illuminate\Contracts\View\View;
2020-12-14 15:30:57 -05:00
use Illuminate\Cookie\CookieValuePrefix;
2022-07-05 04:50:48 +02:00
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Database\Eloquent\Model;
2020-12-14 15:30:57 -05:00
use Illuminate\Encryption\Encrypter;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\RouteCollection;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Session\ArraySessionHandler;
use Illuminate\Session\NullSessionHandler;
use Illuminate\Session\Store;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
use Illuminate\Support\ViewErrorBag;
2021-03-08 11:49:04 -06:00
use Illuminate\Testing\Fluent\AssertableJson;
use Illuminate\Testing\TestResponse;
use JsonSerializable;
use Mockery as m;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\Attributes\TestWith;
2019-02-07 17:04:40 +01:00
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
2020-12-14 15:30:57 -05:00
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
2017-01-31 23:09:17 +02:00
class TestResponseTest extends TestCase
2017-01-31 23:09:17 +02:00
{
public function testAssertViewIs(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'getData' => ['foo' => 'bar'],
2018-12-05 17:59:41 +01:00
'name' => 'dir.my-view',
]);
$response->assertViewIs('dir.my-view');
}
public function testAssertViewHas(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewHas('foo');
}
public function testAssertViewHasModel(): void
{
$model = new TestModel(['id' => 1]);
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => $model],
]);
$response->assertViewHas('foo', $model);
}
public function testAssertViewHasWithClosure(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewHas('foo', function ($value) {
return $value === 'bar';
});
}
public function testAssertViewHasWithValue(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewHas('foo', 'bar');
}
public function testAssertViewHasNested(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => [
'foo' => [
'nested' => 'bar',
],
],
]);
$response->assertViewHas('foo.nested');
}
public function testAssertViewHasWithNestedValue(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => [
'foo' => [
'nested' => 'bar',
],
],
]);
$response->assertViewHas('foo.nested', 'bar');
}
public function testAssertViewHasEloquentCollection(): void
{
2022-07-05 04:50:48 +02:00
$collection = new EloquentCollection([
new TestModel(['id' => 1]),
new TestModel(['id' => 2]),
new TestModel(['id' => 3]),
]);
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foos' => $collection],
]);
$response->assertViewHas('foos', $collection);
}
public function testAssertViewHasEloquentCollectionRespectsOrder(): void
{
2022-07-05 04:50:48 +02:00
$collection = new EloquentCollection([
new TestModel(['id' => 3]),
new TestModel(['id' => 2]),
new TestModel(['id' => 1]),
]);
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foos' => $collection],
]);
$this->expectException(AssertionFailedError::class);
$response->assertViewHas('foos', $collection->reverse()->values());
}
public function testAssertViewHasEloquentCollectionRespectsType(): void
{
2022-07-05 04:50:48 +02:00
$actual = new EloquentCollection([
new TestModel(['id' => 1]),
new TestModel(['id' => 2]),
]);
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foos' => $actual],
]);
2022-07-05 04:50:48 +02:00
$expected = new EloquentCollection([
new AnotherTestModel(['id' => 1]),
new AnotherTestModel(['id' => 2]),
]);
$this->expectException(AssertionFailedError::class);
$response->assertViewHas('foos', $expected);
}
public function testAssertViewHasEloquentCollectionRespectsSize(): void
{
2022-07-05 04:50:48 +02:00
$actual = new EloquentCollection([
new TestModel(['id' => 1]),
new TestModel(['id' => 2]),
]);
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foos' => $actual],
]);
$this->expectException(AssertionFailedError::class);
$response->assertViewHas('foos', $actual->concat([new TestModel(['id' => 3])]));
}
public function testAssertViewHasWithArray(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewHas(['foo' => 'bar']);
}
public function testAssertViewHasAll(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewHasAll([
'foo' => 'bar',
]);
}
public function testAssertViewMissing(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar'],
]);
$response->assertViewMissing('baz');
}
public function testAssertViewMissingNested(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => [
'foo' => [
'nested' => 'bar',
],
],
]);
$response->assertViewMissing('foo.baz');
}
public function testViewData(): void
{
$response = $this->makeMockResponse([
'render' => 'hello world',
'gatherData' => ['foo' => 'bar', 'baz' => 'qux'],
]);
$this->assertEquals('bar', $response->viewData('foo'));
$this->assertEquals(['foo' => 'bar', 'baz' => 'qux'], $response->viewData());
}
public function testAssertContent(): void
{
$response = $this->makeMockResponse([
'render' => 'expected response data',
]);
$response->assertContent('expected response data');
try {
$response->assertContent('expected');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
try {
$response->assertContent('expected response data with extra');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
}
public function testAssertStreamedAndAssertNotStreamed(): void
{
$notStreamedResponse = $this->makeMockResponse([
'render' => 'expected response data',
]);
$streamedResponse = TestResponse::fromBaseResponse(
new StreamedResponse(function () {
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'expected response data');
rewind($stream);
fpassthru($stream);
})
);
$notStreamedResponse->assertNotStreamed();
$streamedResponse->assertStreamed();
try {
$notStreamedResponse->assertStreamed();
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame("Expected the response to be streamed, but it wasn't.\nFailed asserting that false is true.", $e->getMessage());
}
try {
$streamedResponse->assertNotStreamed();
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame("Response was unexpectedly streamed.\nFailed asserting that false is true.", $e->getMessage());
}
}
public function testAssertStreamedContent(): void
{
$response = TestResponse::fromBaseResponse(
new StreamedResponse(function () {
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'expected response data');
rewind($stream);
fpassthru($stream);
})
);
$response->assertStreamedContent('expected response data');
try {
$response->assertStreamedContent('expected');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
try {
$response->assertStreamedContent('expected response data with extra');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
}
public function testAssertStreamedJsonContent(): void
{
$response = TestResponse::fromBaseResponse(
new StreamedJsonResponse([
'data' => $this->yieldTestModels(),
])
);
$response->assertStreamedJsonContent([
'data' => [
['id' => 1],
['id' => 2],
['id' => 3],
],
]);
try {
$response->assertStreamedJsonContent([
'data' => [
['id' => 1],
['id' => 2],
],
]);
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
try {
$response->assertStreamedContent('not expected response string');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
}
public function testAssertStreamedBinaryFile(): void
{
$response = TestResponse::fromBaseResponse(
new BinaryFileResponse(__DIR__.'/Fixtures/file.json')
);
$response->assertStreamedContent('{"foo":"bar"}');
try {
$response->assertStreamedContent('not expected response string');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
}
public function testAssertStreamedJsonFile(): void
{
$response = TestResponse::fromBaseResponse(
new BinaryFileResponse(__DIR__.'/Fixtures/file.json')
);
$response->assertStreamedJsonContent(['foo' => 'bar']);
try {
$response->assertStreamedJsonContent([
'data' => [
['id' => 1],
['id' => 2],
],
]);
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());
}
}
public function testJsonAssertionsOnStreamedJsonContent(): void
{
$response = TestResponse::fromBaseResponse(
new StreamedJsonResponse([
'data' => $this->yieldTestModels(),
])
);
$response->assertJsonPath('data', [
['id' => 1],
['id' => 2],
['id' => 3],
]);
try {
$response->assertJsonPath('data', [
['id' => 1],
['id' => 2],
]);
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that two arrays are identical.', $e->getMessage());
}
$response->assertJsonCount(3, 'data');
try {
$response->assertJsonCount(2, 'data');
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$this->assertSame("Failed to assert that the response count matched the expected 2\nFailed asserting that actual size 3 matches expected size 2.", $e->getMessage());
}
}
public function yieldTestModels()
{
yield new TestModel(['id' => 1]);
yield new TestModel(['id' => 2]);
yield new TestModel(['id' => 3]);
}
public function testAssertSee(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSee('foo');
$response->assertSee(['baz', 'bar']);
}
public function testAssertSeeCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSee('item');
$response->assertSee(['not', 'found']);
}
public function testAssertSeeEscaped(): void
{
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertSee('laravel & php');
$response->assertSee(['php & friends', 'laravel & php']);
}
public function testAssertSeeEscapedCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertSee('foo & bar');
$response->assertSee(['bar & baz', 'baz & qux']);
}
public function testAssertSeeHtml(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeHtml('<li>foo</li>');
$response->assertSeeHtml(['<li>baz</li>', '<li>bar</li>']);
}
public function testAssertSeeHtmlCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeHtml('<li>item</li>');
$response->assertSeeHtml(['<li>not</li>', '<li>found</li>']);
}
public function testAssertSeeInOrder(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeInOrder(['foo', 'bar', 'baz']);
$response->assertSeeInOrder(['foo', 'bar', 'baz', 'foo']);
}
public function testAssertSeeInOrderCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeInOrder(['baz', 'bar', 'foo']);
}
public function testAssertSeeInOrderCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeInOrder(['foo', 'qux', 'bar', 'baz']);
}
public function testAssertSeeHtmlInOrder(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>bar</li>', '<li>baz</li>']);
$response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>bar</li>', '<li>baz</li>', '<li>foo</li>']);
}
public function testAssertSeeHtmlInOrderCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeHtmlInOrder(['<li>baz</li>', '<li>bar</li>', '<li>foo</li>']);
}
public function testAssertSeeHtmlInOrderCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>qux</li>', '<li>bar</li>', '<li>baz</li>']);
}
public function testAssertSeeText(): void
{
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',
]);
$response->assertSeeText('foobar');
$response->assertSeeText(['bazqux', 'foobar']);
}
public function testAssertSeeTextCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that \'foo<strong>bar</strong>\' contains "bazfoo".');
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong>',
]);
$response->assertSeeText('bazfoo');
$response->assertSeeText(['bazfoo', 'barqux']);
}
public function testAssertSeeTextEscaped(): void
{
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertSeeText('laravel & php');
$response->assertSeeText(['php & friends', 'laravel & php']);
}
public function testAssertSeeTextWhitespace(): void
{
$response = $this->makeMockResponse([
'render' => <<<'EOT'
<p>
Hello,
laravel &amp; php &amp; friends
</p>,
EOT
]);
$response->assertSeeText('Hello, laravel & php & friends');
}
public function testAssertSeeTextEscapedCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertSeeText('foo & bar');
$response->assertSeeText(['foo & bar', 'bar & baz']);
}
public function testAssertSeeTextInOrder(): void
{
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',
]);
$response->assertSeeTextInOrder(['foobar', 'baz']);
$response->assertSeeTextInOrder(['foobar', 'baz', 'foo']);
}
public function testAssertSeeTextInOrderEscaped(): void
{
$response = $this->makeMockResponse([
'render' => '<strong>laravel &amp; php</strong> <i>phpstorm &gt; sublime</i>',
]);
$response->assertSeeTextInOrder(['laravel & php', 'phpstorm > sublime']);
}
public function testAssertSeeTextInOrderWhitespace(): void
{
$response = $this->makeMockResponse([
'render' => <<<'EOT'
<p>
Hello,
laravel &amp; php &amp; friends
</p>,
EOT
]);
$response->assertSeeTextInOrder(['Hello', 'laravel & php', 'friends']);
}
public function testAssertSeeTextInOrderCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that \'foo<strong>bar</strong> baz <strong>foo</strong>\' contains "foobar" in specified order.');
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',
]);
$response->assertSeeTextInOrder(['baz', 'foobar']);
}
public function testAssertSeeTextInOrderCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',
]);
$response->assertSeeTextInOrder(['foobar', 'qux', 'baz']);
}
public function testAssertDontSee(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertDontSee('laravel');
$response->assertDontSee(['php', 'friends']);
}
public function testAssertDontSeeCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertDontSee('foo');
$response->assertDontSee(['baz', 'bar']);
}
public function testAssertDontSeeEscaped(): void
{
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertDontSee('foo & bar');
$response->assertDontSee(['bar & baz', 'foo & bar']);
}
public function testAssertDontSeeEscapedCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertDontSee('laravel & php');
$response->assertDontSee(['php & friends', 'laravel & php']);
}
public function testAssertDontSeeHtml(): void
{
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertDontSeeHtml('<li>laravel</li>');
$response->assertDontSeeHtml(['<li>php</li>', '<li>friends</li>']);
}
public function testAssertDontSeeHtmlCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',
]);
$response->assertDontSeeHtml('<li>foo</li>');
$response->assertDontSeeHtml(['<li>baz</li>', '<li>bar</li>']);
}
public function testAssertDontSeeText(): void
{
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',
]);
$response->assertDontSeeText('laravelphp');
$response->assertDontSeeText(['phpfriends', 'laravelphp']);
}
public function testAssertDontSeeTextCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that \'foo<strong>bar</strong>baz<strong>qux</strong>\' does not contain "foobar".');
$response = $this->makeMockResponse([
'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',
]);
$response->assertDontSeeText('foobar');
$response->assertDontSeeText(['bazqux', 'foobar']);
}
public function testAssertDontSeeTextEscaped(): void
{
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertDontSeeText('foo & bar');
$response->assertDontSeeText(['bar & baz', 'foo & bar']);
}
public function testAssertDontSeeTextEscapedCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = $this->makeMockResponse([
'render' => 'laravel &amp; php &amp; friends',
]);
$response->assertDontSeeText('laravel & php');
$response->assertDontSeeText(['php & friends', 'laravel & php']);
}
public function testAssertOk(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertOk();
}
public function testAssertCreated(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertCreated();
}
public function testAssertNotFound(): void
2019-06-18 00:01:59 -03:00
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
2019-06-18 00:01:59 -03:00
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertNotFound();
}
public function testAssertMethodNotAllowed(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_METHOD_NOT_ALLOWED)
);
$response->assertMethodNotAllowed();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [405] but received 200.\nFailed asserting that 200 is identical to 405.");
$response->assertMethodNotAllowed();
}
public function testAssertNotAcceptable(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_NOT_ACCEPTABLE)
);
$response->assertNotAcceptable();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [406] but received 200.\nFailed asserting that 200 is identical to 406.");
$response->assertNotAcceptable();
$this->fail();
}
public function testAssertForbidden(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertForbidden();
}
public function testAssertUnauthorized(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertUnauthorized();
}
public function testAssertBadRequest(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_BAD_REQUEST)
);
$response->assertBadRequest();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [400] but received 200.\nFailed asserting that 200 is identical to 400.");
$response->assertBadRequest();
$this->fail();
}
public function testAssertRequestTimeout(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_REQUEST_TIMEOUT)
);
$response->assertRequestTimeout();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [408] but received 200.\nFailed asserting that 200 is identical to 408.");
$response->assertRequestTimeout();
$this->fail();
}
public function testAssertPaymentRequired(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_PAYMENT_REQUIRED)
);
$response->assertPaymentRequired();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [402] but received 200.\nFailed asserting that 200 is identical to 402.");
$response->assertPaymentRequired();
$this->fail();
}
public function testAssertMovedPermanently(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_MOVED_PERMANENTLY)
);
$response->assertMovedPermanently();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [301] but received 200.\nFailed asserting that 200 is identical to 301.");
$response->assertMovedPermanently();
$this->fail();
}
public function testAssertFound(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_FOUND)
);
$response->assertFound();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [302] but received 200.\nFailed asserting that 200 is identical to 302.");
$response->assertFound();
$this->fail();
}
public function testAssertNotModified(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_NOT_MODIFIED)
);
$response->assertNotModified();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [304] but received 200.\nFailed asserting that 200 is identical to 304.");
$response->assertNotModified();
$this->fail();
}
public function testAssertTemporaryRedirect(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_TEMPORARY_REDIRECT)
);
$response->assertTemporaryRedirect();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [307] but received 200.\nFailed asserting that 200 is identical to 307.");
$response->assertTemporaryRedirect();
$this->fail();
}
public function testAssertPermanentRedirect(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_PERMANENTLY_REDIRECT)
);
$response->assertPermanentRedirect();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [308] but received 200.\nFailed asserting that 200 is identical to 308.");
$response->assertPermanentRedirect();
$this->fail();
}
public function testAssertConflict(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_CONFLICT)
);
$response->assertConflict();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [409] but received 200.\nFailed asserting that 200 is identical to 409.");
$response->assertConflict();
$this->fail();
}
public function testAssertGone(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_GONE)
);
$response->assertGone();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [410] but received 200.\nFailed asserting that 200 is identical to 410.");
$response->assertGone();
}
public function testAssertTooManyRequests(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_TOO_MANY_REQUESTS)
);
$response->assertTooManyRequests();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [429] but received 200.\nFailed asserting that 200 is identical to 429.");
$response->assertTooManyRequests();
$this->fail();
}
public function testAssertAccepted(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_ACCEPTED)
);
$response->assertAccepted();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [202] but received 200.\nFailed asserting that 200 is identical to 202.");
$response->assertAccepted();
$this->fail();
}
public function testAssertUnprocessable(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertUnprocessable();
}
public function testAssertFailedDependency(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_FAILED_DEPENDENCY)
);
$response->assertFailedDependency();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [424] but received 200.\nFailed asserting that 200 is identical to 424.");
$response->assertFailedDependency();
$this->fail();
}
public function testAssertClientError(): void
{
$statusCode = 400;
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertClientError();
}
public function testAssertServerError(): void
{
$statusCode = 500;
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertServerError();
}
public function testAssertInternalServerError(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR)
);
$response->assertInternalServerError();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [500] but received 200.\nFailed asserting that 200 is identical to 500.");
$response->assertInternalServerError();
}
public function testAssertServiceUnavailable(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_SERVICE_UNAVAILABLE)
);
$response->assertServiceUnavailable();
$response = TestResponse::fromBaseResponse(
(new Response)->setStatusCode(Response::HTTP_OK)
);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage("Expected response status code [503] but received 200.\nFailed asserting that 200 is identical to 503.");
$response->assertServiceUnavailable();
}
public function testAssertNoContentAsserts204StatusCodeByDefault(): void
{
$statusCode = 500;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertNoContent();
}
public function testAssertNoContentAssertsExpectedStatusCode(): void
{
$statusCode = 500;
$expectedStatusCode = 418;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertNoContent($expectedStatusCode);
}
public function testAssertNoContentAssertsEmptyContent(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Response content is not empty');
$baseResponse = tap(new Response, function ($response) {
$response->setStatusCode(204);
$response->setContent('non-empty-response-content');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertNoContent();
}
public function testAssertStatus(): void
{
$statusCode = 500;
$expectedStatusCode = 401;
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Expected response status code');
$baseResponse = tap(new Response, function ($response) use ($statusCode) {
$response->setStatusCode($statusCode);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertStatus($expectedStatusCode);
}
public function testAssertHeader(): void
{
$this->expectException(AssertionFailedError::class);
$baseResponse = tap(new Response, function ($response) {
$response->header('Location', '/foo');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertHeader('Location', '/bar');
}
public function testAssertHeaderMissing(): void
{
2019-02-07 17:04:40 +01:00
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessage('Unexpected header [Location] is present on response.');
$baseResponse = tap(new Response, function ($response) {
$response->header('Location', '/foo');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertHeaderMissing('Location');
}
public function testAssertPrecognitionSuccessfulWithMissingHeader(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Header [Precognition-Success] not present on response.');
$baseResponse = new Response('', 204);
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertSuccessfulPrecognition();
}
public function testAssertPrecognitionSuccessfulWithIncorrectValue(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('The Precognition-Success header was found, but the value is not `true`.');
$baseResponse = tap(new Response('', 204), function ($response) {
$response->header('Precognition-Success', '');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertSuccessfulPrecognition();
}
public function testAssertJsonWithArray(): void
2017-01-31 23:09:17 +02:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
2017-01-31 23:09:17 +02:00
$resource = new JsonSerializableSingleResourceStub;
$response->assertJson($resource->jsonSerialize());
}
public function testAssertJsonWithNull(): void
{
$response = TestResponse::fromBaseResponse(new Response(null));
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Invalid JSON was returned from the route.');
$resource = new JsonSerializableSingleResourceStub;
$response->assertJson($resource->jsonSerialize());
}
public function testAssertJsonWithFluent(): void
2021-03-03 20:07:50 +01:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
2021-03-08 11:49:04 -06:00
$response->assertJson(function (AssertableJson $json) {
2021-03-03 20:07:50 +01:00
$json->where('0.foo', 'foo 0');
$json->where('0.meta', []);
2021-03-03 20:07:50 +01:00
});
}
public function testAssertJsonWithFluentFailsWhenNotInteractingWithAllProps(): void
2021-03-03 20:07:50 +01:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
2021-03-03 20:07:50 +01:00
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Unexpected properties were found on the root level.');
2021-03-08 11:49:04 -06:00
$response->assertJson(function (AssertableJson $json) {
$json->where('foo', 'bar');
});
}
public function testAssertJsonWithFluentSkipsInteractionWhenTopLevelKeysNonAssociative(): void
{
$response = TestResponse::fromBaseResponse(new Response([
['foo' => 'bar'],
['foo' => 'baz'],
]));
$response->assertJson(function (AssertableJson $json) {
//
});
2021-03-03 20:07:50 +01:00
}
public function testAssertJsonWithFluentHasAnyThrows(): void
{
$response = TestResponse::fromBaseResponse(new Response([]));
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('None of properties [data, errors, meta] exist.');
$response->assertJson(function (AssertableJson $json) {
$json->hasAny('data', 'errors', 'meta');
});
}
public function testAssertJsonWithFluentHasAnyPasses(): void
{
$response = TestResponse::fromBaseResponse(new Response([
'data' => [],
]));
$response->assertJson(function (AssertableJson $json) {
$json->hasAny('data', 'errors', 'meta');
});
}
public function testAssertSimilarJsonWithMixed(): void
2017-01-31 23:09:17 +02:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
2017-01-31 23:09:17 +02:00
$resource = new JsonSerializableMixedResourcesStub;
$expected = $resource->jsonSerialize();
$response->assertSimilarJson($expected);
$expected['bars'][0] = ['bar' => 'foo 2', 'foo' => 'bar 2'];
$expected['bars'][2] = ['bar' => 'foo 0', 'foo' => 'bar 0'];
$response->assertSimilarJson($expected);
2017-01-31 23:09:17 +02:00
}
public function testAssertExactJsonWithMixedWhenDataIsExactlySame(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$resource = new JsonSerializableMixedResourcesStub;
$expected = $resource->jsonSerialize();
$response->assertExactJson($expected);
}
public function testAssertExactJsonWithMixedWhenDataIsSimilar(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that two strings are equal.');
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$resource = new JsonSerializableMixedResourcesStub;
$expected = $resource->jsonSerialize();
$expected['bars'][0] = ['bar' => 'foo 2', 'foo' => 'bar 2'];
$expected['bars'][2] = ['bar' => 'foo 0', 'foo' => 'bar 0'];
$response->assertExactJson($expected);
}
public function testAssertJsonPath(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$response->assertJsonPath('0.foo', 'foo 0');
$response->assertJsonPath('0.foo', 'foo 0');
$response->assertJsonPath('0.bar', 'bar 0');
$response->assertJsonPath('0.foobar', 'foobar 0');
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$response->assertJsonPath('foo', 'bar');
$response->assertJsonPath('foobar.foobar_foo', 'foo');
$response->assertJsonPath('foobar.foobar_bar', 'bar');
$response->assertJsonPath('foobar.foobar_foo', 'foo')->assertJsonPath('foobar.foobar_bar', 'bar');
$response->assertJsonPath('bars', [
['bar' => 'foo 0', 'foo' => 'bar 0'],
['bar' => 'foo 1', 'foo' => 'bar 1'],
['bar' => 'foo 2', 'foo' => 'bar 2'],
]);
$response->assertJsonPath('bars.0', ['bar' => 'foo 0', 'foo' => 'bar 0']);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonPath('0.id', 10);
$response->assertJsonPath('1.id', 20);
$response->assertJsonPath('2.id', 30);
}
public function testAssertJsonPathCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that 10 is identical to \'10\'.');
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonPath('0.id', '10');
}
public function testAssertJsonPathWithClosure(): void
{
$response = TestResponse::fromBaseResponse(new Response([
'data' => ['foo' => 'bar'],
]));
$response->assertJsonPath('data.foo', fn ($value) => $value === 'bar');
}
public function testAssertJsonPathWithClosureCanFail(): void
{
$response = TestResponse::fromBaseResponse(new Response([
'data' => ['foo' => 'bar'],
]));
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that false is true.');
$response->assertJsonPath('data.foo', fn ($value) => $value === null);
}
public function testAssertJsonPathWithEnum(): void
{
$response = TestResponse::fromBaseResponse(new Response([
'data' => ['status' => 'booked'],
]));
$response->assertJsonPath('data.status', TestStatus::Booked);
}
public function testAssertJsonPathWithEnumCanFail(): void
{
$response = TestResponse::fromBaseResponse(new Response([
'data' => ['status' => 'failed'],
]));
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that two strings are identical.');
$response->assertJsonPath('data.status', TestStatus::Booked);
}
public function testAssertJsonPathCanonicalizing(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$response->assertJsonPathCanonicalizing('*.foo', ['foo 0', 'foo 1', 'foo 2', 'foo 3']);
$response->assertJsonPathCanonicalizing('*.foo', ['foo 1', 'foo 0', 'foo 3', 'foo 2']);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonPathCanonicalizing('*.id', [10, 20, 30]);
$response->assertJsonPathCanonicalizing('*.id', [30, 10, 20]);
}
public function testAssertJsonPathCanonicalizingCanFail(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Failed asserting that two arrays are equal.');
$response->assertJsonPathCanonicalizing('*.foo', ['foo 0', 'foo 2', 'foo 3']);
}
public function testAssertJsonFragment(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$response->assertJsonFragment(['foo' => 'foo 0']);
$response->assertJsonFragment(['foo' => 'foo 0', 'bar' => 'bar 0', 'foobar' => 'foobar 0']);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$response->assertJsonFragment(['foo' => 'bar']);
$response->assertJsonFragment(['foobar_foo' => 'foo']);
$response->assertJsonFragment(['foobar' => ['foobar_foo' => 'foo', 'foobar_bar' => 'bar']]);
$response->assertJsonFragment(['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']]);
2018-10-10 22:24:53 +02:00
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonFragment(['id' => 10]);
}
public function testAssertJsonFragments(): void
2025-02-13 02:21:24 +10:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$response->assertJsonFragments([
['foo' => 'foo 0'],
]);
$response->assertJsonFragments([
['foo' => 'foo 0'],
['foo' => 'foo 1'],
]);
}
public function testAssertJsonFragmentCanFail(): void
{
$this->expectException(AssertionFailedError::class);
2018-10-10 22:24:53 +02:00
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonFragment(['id' => 1]);
}
public function testAssertJsonFragmentUnicodeCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessageMatches('/Привет|Мир/');
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithUnicodeStub));
$response->assertJsonFragment(['id' => 1]);
}
public function testAssertJsonStructure(): void
2017-01-31 23:09:17 +02:00
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
2017-01-31 23:09:17 +02:00
// Without structure
$response->assertJsonStructure();
2017-01-31 23:09:17 +02:00
// At root
$response->assertJsonStructure(['foo']);
// Nested
$response->assertJsonStructure(['foobar' => ['foobar_foo', 'foobar_bar']]);
// Wildcard (repeating structure)
$response->assertJsonStructure(['bars' => ['*' => ['bar', 'foo']]]);
// Wildcard (numeric keys)
$response->assertJsonStructure(['numeric_keys' => ['*' => ['bar', 'foo']]]);
2017-01-31 23:09:17 +02:00
// Nested after wildcard
$response->assertJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo', 'bar']]]]);
// Wildcard (repeating structure) at root
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
2017-01-31 23:09:17 +02:00
$response->assertJsonStructure(['*' => ['foo', 'bar', 'foobar']]);
}
public function testAssertExactJsonStructure(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
// Without structure
$response->assertExactJsonStructure();
// At root
try {
$response->assertExactJsonStructure(['foo']);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['foo', 'foobar', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);
// Nested
try {
$response->assertExactJsonStructure(['foobar' => ['foobar_foo'], 'foo', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['foobar' => ['foobar_foo', 'foobar_bar'], 'foo', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);
// Wildcard (repeating structure)
try {
$response->assertExactJsonStructure(['bars' => ['*' => ['bar']], 'foo', 'foobar', 0, 'baz', 'barfoo', 'numeric_keys']);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['bars' => ['*' => ['bar', 'foo']], 'foo', 'foobar', 0, 'baz', 'barfoo', 'numeric_keys']);
// Wildcard (numeric keys)
try {
$response->assertExactJsonStructure(['numeric_keys' => ['*' => ['bar']], 'foo', 'foobar', 0, 'bars', 'baz', 'barfoo']);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['numeric_keys' => ['*' => ['bar', 'foo']], 'foo', 'foobar', 0, 'bars', 'baz', 'barfoo']);
// Nested after wildcard
try {
$response->assertExactJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo']]], 'foo', 'foobar', 0, 'bars', 'barfoo', 'numeric_keys']);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo', 'bar']]], 'foo', 'foobar', 0, 'bars', 'barfoo', 'numeric_keys']);
// Wildcard (repeating structure) at root
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
try {
$response->assertExactJsonStructure(['*' => ['foo', 'bar']]);
$failed = false;
} catch (AssertionFailedError $e) {
$failed = true;
}
$this->assertTrue($failed);
$response->assertExactJsonStructure(['*' => ['foo', 'bar', 'foobar', 'meta']]);
}
public function testAssertJsonCount(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
// With falsey key
$response->assertJsonCount(1, '0');
// With simple key
$response->assertJsonCount(3, 'bars');
// With nested key
$response->assertJsonCount(1, 'barfoo.0.bar');
$response->assertJsonCount(3, 'barfoo.2.bar');
// Without structure
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$response->assertJsonCount(4);
}
public function testAssertJsonMissing(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonMissing(['id' => 20]);
}
public function testAssertJsonMissingExact(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonMissingExact(['id' => 2]);
// This is missing because bar has changed to baz
$response->assertJsonMissingExact(['id' => 20, 'foo' => 'baz']);
}
public function testAssertJsonMissingExactCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonMissingExact(['id' => 20]);
}
public function testAssertJsonMissingExactCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));
$response->assertJsonMissingExact(['id' => 20, 'foo' => 'bar']);
}
public function testAssertJsonMissingPath(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
// With simple key
$response->assertJsonMissingPath('missing');
// With nested key
$response->assertJsonMissingPath('foobar.missing');
$response->assertJsonMissingPath('numeric_keys.0');
}
public function testAssertJsonMissingPathCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$response->assertJsonMissingPath('foo');
}
public function testAssertJsonMissingPathCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$response->assertJsonMissingPath('foobar.foobar_foo');
}
public function testAssertJsonMissingPathCanFail3(): void
{
$this->expectException(AssertionFailedError::class);
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$response->assertJsonMissingPath('numeric_keys.3');
}
public function testAssertJsonValidationErrors(): void
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors('foo');
}
public function testAssertOnlyJsonValidationErrors(): void
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops', 'bar' => 'another oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
try {
$testResponse->assertOnlyJsonValidationErrors('foo');
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'bar\'', $e->getMessage());
}
$testResponse->assertOnlyJsonValidationErrors(['foo', 'bar']);
try {
$testResponse->assertOnlyJsonValidationErrors(['foo' => 'oops']);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'bar\'', $e->getMessage());
}
$testResponse->assertOnlyJsonValidationErrors(['foo' => 'oops', 'bar' => 'another oops']);
}
public function testAssertJsonValidationErrorsUsingAssertOnlyInvalid(): void
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops', 'bar' => 'another oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response('', 200, ['Content-Type' => 'application/json']))->setContent(json_encode($data))
);
try {
$testResponse->assertOnlyInvalid('foo');
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'bar\'', $e->getMessage());
}
$testResponse->assertOnlyInvalid(['foo', 'bar']);
try {
$testResponse->assertOnlyInvalid(['foo' => 'oops']);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'bar\'', $e->getMessage());
}
$testResponse->assertOnlyInvalid(['foo' => 'oops', 'bar' => 'another oops']);
}
public function testAssertSessionOnlyValidationErrorsUsingAssertOnlyInvalid(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'first_name' => [
'Your first name is required',
'Your first name must be at least 1 character',
],
'last_name' => [
'Your last name is required',
],
]));
$testResponse = TestResponse::fromBaseResponse(new Response);
try {
$testResponse->assertOnlyInvalid('first_name');
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'last_name\'', $e->getMessage());
}
$testResponse->assertOnlyInvalid(['first_name', 'last_name']);
try {
$testResponse->assertOnlyInvalid(['first_name' => 'required']);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith('Response has unexpected validation errors: \'last_name\'', $e->getMessage());
}
$testResponse->assertOnlyInvalid(['first_name' => 'required', 'last_name' => 'required']);
}
public function testAssertJsonValidationErrorsUsingAssertInvalid(): void
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response('', 200, ['Content-Type' => 'application/json']))->setContent(json_encode($data))
);
$testResponse->assertInvalid('foo');
}
public function testAssertSessionValidationErrorsUsingAssertInvalid(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'first_name' => [
'Your first name is required',
'Your first name must be at least 1 character',
],
]));
$testResponse = TestResponse::fromBaseResponse(new Response);
$testResponse->assertValid('last_name');
$testResponse->assertValid(['last_name']);
$testResponse->assertInvalid();
$testResponse->assertInvalid('first_name');
$testResponse->assertInvalid(['first_name']);
$testResponse->assertInvalid(['first_name' => 'required']);
$testResponse->assertInvalid(['first_name' => 'character']);
}
public function testAssertSessionValidationErrorsUsingAssertValid(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
]));
$testResponse = TestResponse::fromBaseResponse(new Response);
$testResponse->assertValid();
}
public function testAssertingKeyIsInvalidErrorMessage(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$testResponse = TestResponse::fromBaseResponse(new Response);
try {
$testResponse->assertInvalid(['input_name']);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith("Failed to find a validation error in session for key: 'input_name'", $e->getMessage());
}
try {
$testResponse->assertInvalid(['input_name' => 'Expected error message.']);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith("Failed to find a validation error in session for key: 'input_name'", $e->getMessage());
}
}
public function testInvalidWithListOfErrors(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'first_name' => [
'Your first name is required',
'Your first name must be at least 1 character',
],
]));
$testResponse = TestResponse::fromBaseResponse(new Response);
$testResponse->assertInvalid(['first_name' => 'Your first name is required']);
$testResponse->assertInvalid(['first_name' => 'Your first name must be at least 1 character']);
$testResponse->assertInvalid(['first_name' => ['Your first name is required', 'Your first name must be at least 1 character']]);
try {
$testResponse->assertInvalid(['first_name' => ['Your first name is required', 'FOO']]);
$this->fail();
} catch (AssertionFailedError $e) {
$this->assertStringStartsWith("Failed to find a validation error for key and message: 'first_name' => 'FOO'", $e->getMessage());
}
}
public function testAssertJsonValidationErrorsCustomErrorsName(): void
{
$data = [
'status' => 'ok',
'data' => ['foo' => 'oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
2019-03-16 16:21:12 +02:00
$testResponse->assertJsonValidationErrors('foo', 'data');
}
public function testAssertJsonValidationErrorsCustomNestedErrorsName(): void
{
$data = [
'status' => 'ok',
'data' => ['errors' => ['foo' => 'oops']],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors('foo', 'data.errors');
}
public function testAssertJsonValidationErrorsCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors('bar');
}
public function testAssertJsonValidationErrorsCanFailWhenThereAreNoErrors(): void
{
$this->expectException(AssertionFailedError::class);
$data = ['status' => 'ok'];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors('bar');
}
public function testAssertJsonValidationErrorsFailsWhenGivenAnEmptyArray(): void
{
$this->expectException(AssertionFailedError::class);
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode(['errors' => ['foo' => 'oops']]))
);
$testResponse->assertJsonValidationErrors([]);
}
public function testAssertJsonValidationErrorsWithArray(): void
2019-06-10 13:51:40 -05:00
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'one', 'bar' => 'two'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['foo', 'bar']);
}
public function testAssertJsonValidationErrorMessages(): void
2019-06-10 13:51:40 -05:00
{
$data = [
'status' => 'ok',
'errors' => ['key' => 'foo'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['key' => 'foo']);
}
public function testAssertJsonValidationErrorContainsMessages(): void
2019-06-10 13:51:40 -05:00
{
$data = [
'status' => 'ok',
'errors' => ['key' => 'foo bar'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['key' => 'foo']);
}
public function testAssertJsonValidationErrorMessagesCanFail(): void
2019-06-10 13:51:40 -05:00
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => ['key' => 'foo'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['key' => 'bar']);
}
public function testAssertJsonValidationErrorMessageKeyCanFail(): void
2019-06-10 13:51:40 -05:00
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => ['foo' => 'value'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['bar' => 'value']);
}
public function testAssertJsonValidationErrorMessagesMultipleMessages(): void
2019-06-10 13:51:40 -05:00
{
$data = [
'status' => 'ok',
'errors' => ['one' => 'foo', 'two' => 'bar'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => 'foo', 'two' => 'bar']);
}
public function testAssertJsonValidationErrorMessagesMultipleMessagesCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => ['one' => 'foo', 'two' => 'bar'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => 'foo', 'three' => 'baz']);
}
public function testAssertJsonValidationErrorMessagesMixed(): void
2019-06-10 13:51:40 -05:00
{
$data = [
'status' => 'ok',
'errors' => ['one' => 'foo', 'two' => 'bar'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => 'foo', 'two']);
}
public function testAssertJsonValidationErrorMessagesMixedCanFail(): void
2019-06-10 13:51:40 -05:00
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => ['one' => 'foo', 'two' => 'bar'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => 'taylor', 'otwell']);
}
public function testAssertJsonValidationErrorMessagesMultipleErrors(): void
{
$data = [
'status' => 'ok',
'errors' => [
'one' => [
'First error message.',
'Second error message.',
],
],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => ['First error message.', 'Second error message.']]);
}
public function testAssertJsonValidationErrorMessagesMultipleErrorsCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$data = [
'status' => 'ok',
'errors' => [
'one' => [
'First error message.',
],
],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonValidationErrors(['one' => ['First error message.', 'Second error message.']]);
}
public function testAssertJsonMissingValidationErrors(): void
{
$baseResponse = tap(new Response, function ($response) {
$response->setContent(json_encode(['errors' => [
2019-12-31 00:06:15 +00:00
'foo' => [],
'bar' => ['one', 'two'],
]]));
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertJsonMissingValidationErrors('baz');
$baseResponse = tap(new Response, function ($response) {
$response->setContent(json_encode(['foo' => 'bar']));
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertJsonMissingValidationErrors('foo');
2018-06-13 17:57:34 +02:00
}
public function testAssertJsonMissingValidationErrorsCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$baseResponse = tap(new Response, function ($response) {
$response->setContent(json_encode(['errors' => [
2019-12-31 00:06:15 +00:00
'foo' => [],
'bar' => ['one', 'two'],
]]));
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertJsonMissingValidationErrors('foo');
}
public function testAssertJsonMissingValidationErrorsCanFail2(): void
{
$this->expectException(AssertionFailedError::class);
$baseResponse = tap(new Response, function ($response) {
$response->setContent(json_encode(['errors' => [
2019-12-31 00:06:15 +00:00
'foo' => [],
'bar' => ['one', 'two'],
]]));
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertJsonMissingValidationErrors('bar');
}
public function testAssertJsonMissingValidationErrorsCanFail3(): void
{
$this->expectException(AssertionFailedError::class);
$baseResponse = tap(new Response, function ($response) {
$response->setContent(
json_encode([
'data' => [
'errors' => [
'foo' => ['one'],
],
],
]),
);
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertJsonMissingValidationErrors('foo', 'data.errors');
}
public function testAssertJsonMissingValidationErrorsWithoutArgument(): void
{
$data = ['status' => 'ok'];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonMissingValidationErrors();
}
public function testAssertJsonMissingValidationErrorsWithoutArgumentWhenErrorsIsEmpty(): void
{
$data = ['status' => 'ok', 'errors' => []];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonMissingValidationErrors();
}
public function testAssertJsonMissingValidationErrorsWithoutArgumentCanFail(): void
{
$this->expectException(AssertionFailedError::class);
$data = ['errors' => ['foo' => []]];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonMissingValidationErrors();
}
public function testAssertJsonMissingValidationErrorsOnInvalidJson(): void
2019-06-21 17:31:47 +02:00
{
$this->expectException(AssertionFailedError::class);
2019-06-21 17:31:47 +02:00
$this->expectExceptionMessage('Invalid JSON was returned from the route.');
2019-06-21 17:33:02 +02:00
$invalidJsonResponse = TestResponse::fromBaseResponse(
2019-06-21 17:31:47 +02:00
(new Response)->setContent('~invalid json')
);
2019-06-21 17:31:47 +02:00
2019-06-21 17:33:02 +02:00
$invalidJsonResponse->assertJsonMissingValidationErrors();
}
public function testAssertJsonMissingValidationErrorsCustomErrorsName(): void
{
$data = [
'status' => 'ok',
'data' => ['foo' => 'oops'],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
2019-03-16 16:21:12 +02:00
$testResponse->assertJsonMissingValidationErrors('bar', 'data');
}
public function testAssertJsonMissingValidationErrorsNestedCustomErrorsName1(): void
{
$data = [
'status' => 'ok',
'data' => [
'errors' => ['foo' => 'oops'],
],
];
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode($data))
);
$testResponse->assertJsonMissingValidationErrors('bar', 'data.errors');
}
public function testAssertJsonMissingValidationErrorsNestedCustomErrorsName2(): void
{
$testResponse = TestResponse::fromBaseResponse(
(new Response)->setContent(json_encode([]))
);
$testResponse->assertJsonMissingValidationErrors('bar', 'data.errors');
}
public function testAssertJsonIsArray(): void
{
$responseArray = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$responseArray->assertJsonIsArray();
}
public function testAssertJsonIsNotArray(): void
{
$this->expectException(ExpectationFailedException::class);
$responseObject = TestResponse::fromBaseResponse(new Response([
'foo' => 'bar',
]));
$responseObject->assertJsonIsArray();
}
public function testAssertJsonIsObject(): void
{
$responseObject = TestResponse::fromBaseResponse(new Response([
'foo' => 'bar',
]));
$responseObject->assertJsonIsObject();
}
public function testAssertJsonIsNotObject(): void
{
$this->expectException(ExpectationFailedException::class);
$responseArray = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));
$responseArray->assertJsonIsObject();
}
public function testAssertDownloadOffered(): void
{
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$testResponse = TestResponse::fromBaseResponse(new Response(
$files->get($tempDir.'/file.txt'), 200, [
'Content-Disposition' => 'attachment; filename=file.txt',
]
));
$testResponse->assertDownload();
$files->deleteDirectory($tempDir);
}
public function testAssertDownloadOfferedWithAFileName(): void
{
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$testResponse = TestResponse::fromBaseResponse(new Response(
$files->get($tempDir.'/file.txt'), 200, [
'Content-Disposition' => 'attachment; filename = file.txt',
]
));
$testResponse->assertDownload('file.txt');
$files->deleteDirectory($tempDir);
}
public function testAssertDownloadOfferedWorksWithBinaryFileResponse(): void
{
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$testResponse = TestResponse::fromBaseResponse(new BinaryFileResponse(
$tempDir.'/file.txt', 200, [], true, 'attachment'
));
$testResponse->assertDownload('file.txt');
$files->deleteDirectory($tempDir);
}
public function testAssertDownloadOfferedFailsWithInlineContentDisposition(): void
{
$this->expectException(AssertionFailedError::class);
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$testResponse = TestResponse::fromBaseResponse(new BinaryFileResponse(
$tempDir.'/file.txt', 200, [], true, 'inline'
));
$testResponse->assertDownload();
$files->deleteDirectory($tempDir);
}
public function testAssertDownloadOfferedWithAFileNameWithSpacesInIt(): void
{
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$testResponse = TestResponse::fromBaseResponse(new Response(
$files->get($tempDir.'/file.txt'), 200, [
'Content-Disposition' => 'attachment; filename = "test file.txt"',
]
));
$testResponse->assertDownload('test file.txt');
$files->deleteDirectory($tempDir);
}
public function testMacroable(): void
{
TestResponse::macro('foo', function () {
return 'bar';
});
$response = TestResponse::fromBaseResponse(new Response);
$this->assertSame(
'bar', $response->foo()
);
}
public function testCanBeCreatedFromBinaryFileResponses(): void
{
$files = new Filesystem;
$tempDir = __DIR__.'/tmp';
$files->makeDirectory($tempDir, 0755, false, true);
$files->put($tempDir.'/file.txt', 'Hello World');
$response = TestResponse::fromBaseResponse(new BinaryFileResponse($tempDir.'/file.txt'));
$this->assertEquals($tempDir.'/file.txt', $response->getFile()->getPathname());
$files->deleteDirectory($tempDir);
}
public function testJsonHelper(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$this->assertSame('foo', $response->json('foobar.foobar_foo'));
$this->assertEquals(
json_decode($response->getContent(), true),
$response->json()
);
}
public function testResponseCanBeReturnedAsCollection(): void
{
$response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));
$this->assertInstanceOf(Collection::class, $response->collect());
$this->assertEquals(collect([
'foo' => 'bar',
'foobar' => [
'foobar_foo' => 'foo',
'foobar_bar' => 'bar',
],
'0' => ['foo'],
'bars' => [
['bar' => 'foo 0', 'foo' => 'bar 0'],
['bar' => 'foo 1', 'foo' => 'bar 1'],
['bar' => 'foo 2', 'foo' => 'bar 2'],
],
'baz' => [
['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']],
['foo' => 'bar 1', 'bar' => ['foo' => 'bar 1', 'bar' => 'foo 1']],
],
'barfoo' => [
['bar' => ['bar' => 'foo 0']],
['bar' => ['bar' => 'foo 0', 'foo' => 'foo 0']],
['bar' => ['foo' => 'bar 0', 'bar' => 'foo 0', 'rab' => 'rab 0']],
],
'numeric_keys' => [
2 => ['bar' => 'foo 0', 'foo' => 'bar 0'],
3 => ['bar' => 'foo 1', 'foo' => 'bar 1'],
4 => ['bar' => 'foo 2', 'foo' => 'bar 2'],
],
]), $response->collect());
$this->assertEquals(collect(['foobar_foo' => 'foo', 'foobar_bar' => 'bar']), $response->collect('foobar'));
$this->assertEquals(collect(['bar']), $response->collect('foobar.foobar_bar'));
$this->assertEquals(collect(), $response->collect('missing_key'));
}
public function testItCanBeTapped(): void
2019-07-02 18:53:33 +02:00
{
$response = TestResponse::fromBaseResponse(
(new Response)->setContent('')->setStatusCode(418)
);
$response->tap(function ($response) {
$this->assertInstanceOf(TestResponse::class, $response);
})->assertStatus(418);
}
public function testAssertPlainCookie(): void
2020-12-14 15:30:57 -05:00
{
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie('cookie-name', 'cookie-value'))
2020-12-14 15:30:57 -05:00
);
$response->assertPlainCookie('cookie-name', 'cookie-value');
}
public function testAssertCookie(): void
2020-12-14 15:30:57 -05:00
{
$container = Container::getInstance();
$encrypter = new Encrypter(str_repeat('a', 16));
$container->instance('encrypter', $encrypter);
2020-12-14 15:30:57 -05:00
$cookieName = 'cookie-name';
$cookieValue = 'cookie-value';
$encryptedValue = $encrypter->encrypt(CookieValuePrefix::create($cookieName, $encrypter->getKey()).$cookieValue, false);
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie($cookieName, $encryptedValue))
2020-12-14 15:30:57 -05:00
);
$response->assertCookie($cookieName, $cookieValue);
}
public function testAssertCookieExpired(): void
2020-12-14 15:30:57 -05:00
{
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', time() - 5000))
2020-12-14 15:30:57 -05:00
);
$response->assertCookieExpired('cookie-name');
}
public function testAssertSessionCookieExpiredDoesNotTriggerOnSessionCookies(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', 0))
);
$this->expectException(ExpectationFailedException::class);
$response->assertCookieExpired('cookie-name');
}
public function testAssertCookieNotExpired(): void
2020-12-14 15:30:57 -05:00
{
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', time() + 5000))
2020-12-14 15:30:57 -05:00
);
$response->assertCookieNotExpired('cookie-name');
}
public function testAssertSessionCookieNotExpired(): void
{
$response = TestResponse::fromBaseResponse(
(new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', 0))
);
$response->assertCookieNotExpired('cookie-name');
}
public function testAssertCookieMissing(): void
2020-12-14 15:30:57 -05:00
{
$response = TestResponse::fromBaseResponse(new Response);
2020-12-14 15:30:57 -05:00
$response->assertCookieMissing('cookie-name');
}
public function testAssertLocation(): void
{
app()->instance('url', $url = new UrlGenerator(new RouteCollection, new Request));
$response = TestResponse::fromBaseResponse(
2023-03-13 03:00:40 +00:00
new RedirectResponse($url->to('https://foo.com'))
);
$response->assertLocation('https://foo.com');
$this->expectException(ExpectationFailedException::class);
$response->assertLocation('https://foo.net');
}
public function testAssertRedirectContains(): void
2021-10-13 22:17:07 +02:00
{
$response = TestResponse::fromBaseResponse(
(new Response('', 302))->withHeaders(['Location' => 'https://url.com'])
);
$response->assertRedirectContains('url.com');
2021-10-13 22:17:07 +02:00
$this->expectException(ExpectationFailedException::class);
$response->assertRedirectContains('url.net');
2021-10-13 22:17:07 +02:00
}
public function testAssertHeaderContainsSuccess(): void
{
$baseResponse = tap(new Response, function ($response) {
$response->headers->set('X-Custom-Header', 'prefix-value-suffix');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$response->assertHeaderContains('X-Custom-Header', 'value');
}
public function testAssertHeaderContainsFailure(): void
{
$baseResponse = tap(new Response, function ($response) {
$response->headers->set('X-Custom-Header', 'unrelated');
});
$response = TestResponse::fromBaseResponse($baseResponse);
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Header [X-Custom-Header] was found, but [unrelated] does not contain [value].');
$response->assertHeaderContains('X-Custom-Header', 'value');
}
public function testAssertRedirect(): void
{
$response = TestResponse::fromBaseResponse(
(new Response('', 302))->withHeaders(['Location' => 'https://url.com'])
);
$response->assertRedirect();
}
public function testAssertRedirectBack(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->setPreviousUrl('https://url.com');
app('url')->setSessionResolver(fn () => app('session.store'));
$response = TestResponse::fromBaseResponse(
(new Response('', 302))->withHeaders(['Location' => 'https://url.com'])
);
$response->assertRedirectBack();
$this->expectException(ExpectationFailedException::class);
$store->setPreviousUrl('https://url.net');
$response->assertRedirectBack();
}
public function testGetDecryptedCookie(): void
2020-12-14 15:30:57 -05:00
{
$response = TestResponse::fromBaseResponse(
(new Response())->withCookie(new Cookie('cookie-name', 'cookie-value'))
);
2020-12-14 15:33:53 -05:00
$cookie = $response->getCookie('cookie-name', false);
2020-12-14 15:30:57 -05:00
$this->assertInstanceOf(Cookie::class, $cookie);
2022-02-22 15:46:19 +01:00
$this->assertSame('cookie-name', $cookie->getName());
$this->assertSame('cookie-value', $cookie->getValue());
2020-12-14 15:30:57 -05:00
}
public function testAssertSessionHasErrors(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'foo' => [
'foo is required',
],
]));
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasErrors(['foo']);
}
public function testAssertJsonSerializedSessionHasErrors(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1), null, 'json'));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'foo' => [
'foo is required',
],
]));
$store->save(); // Required to serialize error bag to JSON
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasErrors(['foo']);
}
public function testAssertSessionDoesntHaveErrors(): void
{
$this->expectException(AssertionFailedError::class);
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'foo' => [
'foo is required',
],
]));
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionDoesntHaveErrors(['foo']);
}
public function testAssertSessionHasNoErrors(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('errors', $errorBag = new ViewErrorBag);
$errorBag->put('default', new MessageBag([
'foo' => [
'foo is required',
],
]));
$errorBag->put('some-other-bag', new MessageBag([
'bar' => [
'bar is required',
],
]));
$response = TestResponse::fromBaseResponse(new Response());
try {
$response->assertSessionHasNoErrors();
} catch (AssertionFailedError $e) {
$this->assertStringContainsString('foo is required', $e->getMessage());
$this->assertStringContainsString('bar is required', $e->getMessage());
}
}
public function testAssertSessionHas(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'value');
$store->put('bar', 'value');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHas('foo');
$response->assertSessionHas('bar');
$response->assertSessionHas(['foo', 'bar']);
}
public function testAssertSessionHasAllWithValues(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'apple');
$store->put('bar', 'banana');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasAll([
'foo' => 'apple',
'bar' => 'banana',
]);
}
public function testAssertSessionHasAllShowsAllMismatches(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'wrong1');
$store->put('bar', 'wrong2');
$response = TestResponse::fromBaseResponse(new Response());
try {
$response->assertSessionHasAll([
'foo' => 'apple',
'bar' => 'banana',
]);
$this->fail('xxxx');
} catch (AssertionFailedError $e) {
$diff = $e->getComparisonFailure()->getDiff();
$this->assertStringContainsString('wrong1', $diff);
$this->assertStringContainsString('wrong2', $diff);
$this->assertStringContainsString('apple', $diff);
$this->assertStringContainsString('banana', $diff);
}
}
public function testAssertSessionHasAllWithMixedKeys(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'apple');
$store->put('bar', 'banana');
$store->put('baz', 'cherry');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasAll([
'baz',
'foo' => 'apple',
'bar' => 'banana',
]);
}
public function testAssertSessionHasAllWithClosures(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'apple');
$store->put('bar', 'banana');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasAll([
'foo' => fn ($value) => $value === 'apple',
'bar' => 'banana',
]);
}
public function testAssertSessionMissing(): void
{
$this->expectException(AssertionFailedError::class);
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'value');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionMissing('foo');
}
#[TestWith(['foo', 'goodvalue'])]
#[TestWith([['foo', 'bar'], 'goodvalue'])]
public function testAssertSessionMissingValueIsPresent(array|string $key, mixed $value): void
{
$this->expectException(AssertionFailedError::class);
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'goodvalue');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionMissing($key, $value);
}
public function testAssertSessionMissingValueIsPresentClosure(): void
{
$this->expectException(AssertionFailedError::class);
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'goodvalue');
$key = 'foo';
$value = function ($value) {
return $value === 'goodvalue';
};
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionMissing($key, $value);
}
#[TestWith(['foo', 'badvalue'])]
public function testAssertSessionMissingValueIsMissing(array|string $key, mixed $value): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'goodvalue');
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionMissing($key, $value);
}
public function testAssertSessionMissingValueIsMissingClosure(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('foo', 'goodvalue');
$key = 'foo';
$value = function ($value) {
return $value === 'badvalue';
};
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionMissing($key, $value);
}
public function testAssertSessionHasInput(): void
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));
$store->put('_old_input', [
'foo' => 'value',
'bar' => 'value',
]);
$response = TestResponse::fromBaseResponse(new Response());
$response->assertSessionHasInput('foo');
$response->assertSessionHasInput('foo', 'value');
$response->assertSessionHasInput('bar');
$response->assertSessionHasInput('bar', 'value');
$response->assertSessionHasInput(['foo', 'bar']);
$response->assertSessionHasInput('foo', function ($value) {
return $value === 'value';
});
}
public function testGetEncryptedCookie(): void
2020-12-14 15:30:57 -05:00
{
$container = Container::getInstance();
$encrypter = new Encrypter(str_repeat('a', 16));
$container->instance('encrypter', $encrypter);
2020-12-14 15:30:57 -05:00
$cookieName = 'cookie-name';
$cookieValue = 'cookie-value';
$encryptedValue = $encrypter->encrypt(
CookieValuePrefix::create($cookieName, $encrypter->getKey()).$cookieValue, false
);
$response = TestResponse::fromBaseResponse(
(new Response())->withCookie(new Cookie($cookieName, $encryptedValue))
);
2020-12-14 15:33:53 -05:00
$cookie = $response->getCookie($cookieName);
2020-12-14 15:30:57 -05:00
$this->assertInstanceOf(Cookie::class, $cookie);
$this->assertEquals($cookieName, $cookie->getName());
$this->assertEquals($cookieValue, $cookie->getValue());
}
public function testHandledExceptionIsIncludedInAssertionFailure(): void
{
$response = TestResponse::fromBaseResponse(new Response('', 500))
->withExceptions(collect([new Exception('Unexpected exception.')]));
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessageMatches('/Expected response status code \[200\] but received 500.*Exception: Unexpected exception/s');
$response->assertStatus(200);
}
public function testValidationErrorsAreIncludedInAssertionFailure(): void
{
$response = TestResponse::fromBaseResponse(
tap(new RedirectResponse('/'))
->setSession(new Store('test-session', new NullSessionHandler()))
->withErrors([
'first_name' => 'The first name field is required.',
'last_name' => 'The last name field is required.',
])
);
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessageMatches('/Expected response status code \[200\] but received 302.*The first name field is required.*The last name field is required/s');
$response->assertStatus(200);
}
public function testJsonErrorsAreIncludedInAssertionFailure(): void
{
$response = TestResponse::fromBaseResponse(new JsonResponse([
'errors' => [
'first_name' => ['The first name field is required.'],
'last_name' => ['The last name field is required.'],
],
], 422));
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessageMatches('/Expected response status code \[200\] but received 422.*The first name field is required.*The last name field is required/s');
$response->assertStatus(200);
}
public function testItHandlesFalseJson(): void
{
$response = TestResponse::fromBaseResponse(
new Response(false, 422, ['Content-Type' => 'application/json'])
);
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessage('Expected response status code [200] but received 422.');
$response->assertStatus(200);
}
public function testItHandlesEncodedJson(): void
{
$response = TestResponse::fromBaseResponse(
new Response('b"x£½V*.I,)-V▓R╩¤V¬\x05\x00+ü\x059"', 422, ['Content-Type' => 'application/json', 'Content-Encoding' => 'gzip'])
);
$this->expectException(ExpectationFailedException::class);
$this->expectExceptionMessage('Expected response status code [200] but received 422.');
$response->assertStatus(200);
}
private function makeMockResponse($content)
{
$baseResponse = tap(new Response, function ($response) use ($content) {
$response->setContent(m::mock(View::class, $content));
});
return TestResponse::fromBaseResponse($baseResponse);
}
2017-01-31 23:09:17 +02:00
}
class JsonSerializableMixedResourcesStub implements JsonSerializable
{
public function jsonSerialize(): array
2017-01-31 23:09:17 +02:00
{
return [
'foo' => 'bar',
2017-01-31 23:09:17 +02:00
'foobar' => [
'foobar_foo' => 'foo',
'foobar_bar' => 'bar',
],
'0' => ['foo'],
'bars' => [
2017-01-31 23:09:17 +02:00
['bar' => 'foo 0', 'foo' => 'bar 0'],
['bar' => 'foo 1', 'foo' => 'bar 1'],
['bar' => 'foo 2', 'foo' => 'bar 2'],
],
'baz' => [
2017-01-31 23:09:17 +02:00
['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']],
['foo' => 'bar 1', 'bar' => ['foo' => 'bar 1', 'bar' => 'foo 1']],
],
'barfoo' => [
['bar' => ['bar' => 'foo 0']],
['bar' => ['bar' => 'foo 0', 'foo' => 'foo 0']],
['bar' => ['foo' => 'bar 0', 'bar' => 'foo 0', 'rab' => 'rab 0']],
],
'numeric_keys' => [
2 => ['bar' => 'foo 0', 'foo' => 'bar 0'],
3 => ['bar' => 'foo 1', 'foo' => 'bar 1'],
4 => ['bar' => 'foo 2', 'foo' => 'bar 2'],
],
2017-01-31 23:09:17 +02:00
];
}
}
class JsonSerializableSingleResourceStub implements JsonSerializable
{
public function jsonSerialize(): array
2017-01-31 23:09:17 +02:00
{
return [
['foo' => 'foo 0', 'bar' => 'bar 0', 'foobar' => 'foobar 0', 'meta' => []],
['foo' => 'foo 1', 'bar' => 'bar 1', 'foobar' => 'foobar 1', 'meta' => null],
['foo' => 'foo 2', 'bar' => 'bar 2', 'foobar' => 'foobar 2', 'meta' => []],
['foo' => 'foo 3', 'bar' => 'bar 3', 'foobar' => 'foobar 3', 'meta' => null],
2017-01-31 23:09:17 +02:00
];
}
}
class JsonSerializableSingleResourceWithIntegersStub implements JsonSerializable
{
public function jsonSerialize(): array
{
return [
['id' => 10, 'foo' => 'bar'],
['id' => 20, 'foo' => 'bar'],
['id' => 30, 'foo' => 'bar'],
];
}
}
class JsonSerializableSingleResourceWithUnicodeStub implements JsonSerializable
{
public function jsonSerialize(): array
{
return [
['id' => 10, 'foo' => 'bar'],
['id' => 20, 'foo' => 'Привет'],
['id' => 30, 'foo' => 'Мир'],
];
}
}
class TestModel extends Model
{
protected $guarded = [];
}
class AnotherTestModel extends Model
{
protected $guarded = [];
}
enum TestStatus: string
{
case Booked = 'booked';
}