From 073068c36e5b413832bc8cf7596bac3a2a791a79 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 5 Dec 2016 12:38:15 -0600 Subject: [PATCH] Simplify built-in testing in prep for Dusk. (#16667) Simplifies built-in testing and cleans up architecture in prep for Dusk integration. --- .../Testing/Concerns/ImpersonatesUsers.php | 34 - .../Concerns/InteractsWithAuthentication.php | 30 + .../Testing/Concerns/InteractsWithConsole.php | 9 +- .../Concerns/InteractsWithDatabase.php | 26 - .../Testing/Concerns/InteractsWithPages.php | 759 ------------------ .../Testing/Concerns/InteractsWithSession.php | 178 ---- .../Testing/Concerns/MakesHttpRequests.php | 656 ++------------- .../Concerns/MocksApplicationServices.php | 132 --- .../Foundation/Testing/TestCase.php | 2 - .../Foundation/Testing/TestResponse.php | 320 ++++++++ .../FoundationExpectsModelEventsTest.php | 233 ------ .../FoundationInteractsWithPagesTest.php | 471 ----------- .../FoundationInteractsWithPagesUnitTest.php | 170 ---- .../FoundationMakesHttpRequestsJsonTest.php | 127 --- 14 files changed, 401 insertions(+), 2746 deletions(-) delete mode 100644 src/Illuminate/Foundation/Testing/Concerns/ImpersonatesUsers.php delete mode 100644 src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php delete mode 100644 src/Illuminate/Foundation/Testing/Concerns/InteractsWithSession.php create mode 100644 src/Illuminate/Foundation/Testing/TestResponse.php delete mode 100644 tests/Foundation/FoundationExpectsModelEventsTest.php delete mode 100644 tests/Foundation/FoundationInteractsWithPagesTest.php delete mode 100644 tests/Foundation/FoundationInteractsWithPagesUnitTest.php delete mode 100644 tests/Foundation/FoundationMakesHttpRequestsJsonTest.php diff --git a/src/Illuminate/Foundation/Testing/Concerns/ImpersonatesUsers.php b/src/Illuminate/Foundation/Testing/Concerns/ImpersonatesUsers.php deleted file mode 100644 index 230f79155d93..000000000000 --- a/src/Illuminate/Foundation/Testing/Concerns/ImpersonatesUsers.php +++ /dev/null @@ -1,34 +0,0 @@ -be($user, $driver); - } - - /** - * Set the currently logged in user for the application. - * - * @param \Illuminate\Contracts\Auth\Authenticatable $user - * @param string|null $driver - * @return $this - */ - public function be(UserContract $user, $driver = null) - { - $this->app['auth']->guard($driver)->setUser($user); - - return $this; - } -} diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php index 4e8884c1057f..ee3d005f5c47 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php @@ -2,8 +2,38 @@ namespace Illuminate\Foundation\Testing\Concerns; +use Illuminate\Contracts\Auth\Authenticatable as UserContract; + trait InteractsWithAuthentication { + /** + * Set the currently logged in user for the application. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string|null $driver + * @return $this + */ + public function actingAs(UserContract $user, $driver = null) + { + $this->be($user, $driver); + + return $this; + } + + /** + * Set the currently logged in user for the application. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string|null $driver + * @return void + */ + public function be(UserContract $user, $driver = null) + { + $this->app['auth']->guard($driver)->setUser($user); + + $this->app['auth']->shouldUse($driver); + } + /** * Assert that the user is authenticated. * diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php index b7eaffb6de65..ba078b3149fe 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php @@ -6,13 +6,6 @@ trait InteractsWithConsole { - /** - * The last code returned by Artisan CLI. - * - * @var int - */ - protected $code; - /** * Call artisan command and return code. * @@ -22,6 +15,6 @@ trait InteractsWithConsole */ public function artisan($command, $parameters = []) { - return $this->code = $this->app[Kernel::class]->call($command, $parameters); + return $this->app[Kernel::class]->call($command, $parameters); } } diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php index adcbdf500e4a..61ca782304b2 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php @@ -27,19 +27,6 @@ protected function seeInDatabase($table, array $data, $connection = null) return $this; } - /** - * Assert that a given where condition does not exist in the database. - * - * @param string $table - * @param array $data - * @param string $connection - * @return $this - */ - protected function missingFromDatabase($table, array $data, $connection = null) - { - return $this->notSeeInDatabase($table, $data, $connection); - } - /** * Assert that a given where condition does not exist in the database. * @@ -49,19 +36,6 @@ protected function missingFromDatabase($table, array $data, $connection = null) * @return $this */ protected function dontSeeInDatabase($table, array $data, $connection = null) - { - return $this->notSeeInDatabase($table, $data, $connection); - } - - /** - * Assert that a given where condition does not exist in the database. - * - * @param string $table - * @param array $data - * @param string $connection - * @return $this - */ - protected function notSeeInDatabase($table, array $data, $connection = null) { $database = $this->app->make('db'); diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php deleted file mode 100644 index 6145937bca88..000000000000 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php +++ /dev/null @@ -1,759 +0,0 @@ -makeRequest('GET', $uri); - } - - /** - * Visit the given named route with a GET request. - * - * @param string $route - * @param array $parameters - * @return $this - */ - public function visitRoute($route, $parameters = []) - { - return $this->makeRequest('GET', route($route, $parameters)); - } - - /** - * Make a request to the application and create a Crawler instance. - * - * @param string $method - * @param string $uri - * @param array $parameters - * @param array $cookies - * @param array $files - * @return $this - */ - protected function makeRequest($method, $uri, $parameters = [], $cookies = [], $files = []) - { - $uri = $this->prepareUrlForRequest($uri); - - $this->call($method, $uri, $parameters, $cookies, $files); - - $this->clearInputs()->followRedirects()->assertPageLoaded($uri); - - $this->currentUri = $this->app->make('request')->fullUrl(); - - $this->crawler = new Crawler($this->response->getContent(), $this->currentUri); - - return $this; - } - - /** - * Clean the crawler and the subcrawlers values to reset the page context. - * - * @return $this - */ - protected function resetPageContext() - { - $this->crawler = null; - - $this->subCrawlers = []; - - return $this; - } - - /** - * Make a request to the application using the given form. - * - * @param \Symfony\Component\DomCrawler\Form $form - * @param array $uploads - * @return $this - */ - protected function makeRequestUsingForm(Form $form, array $uploads = []) - { - $files = $this->convertUploadsForTesting($form, $uploads); - - return $this->makeRequest( - $form->getMethod(), $form->getUri(), $this->extractParametersFromForm($form), [], $files - ); - } - - /** - * Extract the parameters from the given form. - * - * @param \Symfony\Component\DomCrawler\Form $form - * @return array - */ - protected function extractParametersFromForm(Form $form) - { - parse_str(http_build_query($form->getValues()), $parameters); - - return $parameters; - } - - /** - * Follow redirects from the last response. - * - * @return $this - */ - protected function followRedirects() - { - while ($this->response->isRedirect()) { - $this->makeRequest('GET', $this->response->getTargetUrl()); - } - - return $this; - } - - /** - * Clear the inputs for the current page. - * - * @return $this - */ - protected function clearInputs() - { - $this->inputs = []; - - $this->uploads = []; - - return $this; - } - - /** - * Assert that the current page matches a given URI. - * - * @param string $uri - * @return $this - */ - protected function seePageIs($uri) - { - $this->assertPageLoaded($uri = $this->prepareUrlForRequest($uri)); - - $this->assertEquals( - $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n" - ); - - return $this; - } - - /** - * Assert that the current page matches a given named route. - * - * @param string $route - * @param array $parameters - * @return $this - */ - protected function seeRouteIs($route, $parameters = []) - { - return $this->seePageIs(route($route, $parameters)); - } - - /** - * Assert that a given page successfully loaded. - * - * @param string $uri - * @param string|null $message - * @return $this - * - * @throws \Illuminate\Foundation\Testing\HttpException - */ - protected function assertPageLoaded($uri, $message = null) - { - $status = $this->response->getStatusCode(); - - try { - $this->assertEquals(200, $status); - } catch (PHPUnitException $e) { - $message = $message ?: "A request to [{$uri}] failed. Received status code [{$status}]."; - - $responseException = isset($this->response->exception) - ? $this->response->exception : null; - - throw new HttpException($message, null, $responseException); - } - - return $this; - } - - /** - * Narrow the test content to a specific area of the page. - * - * @param string $element - * @param \Closure $callback - * @return $this - */ - public function within($element, Closure $callback) - { - $this->subCrawlers[] = $this->crawler()->filter($element); - - $callback(); - - array_pop($this->subCrawlers); - - return $this; - } - - /** - * Get the current crawler according to the test context. - * - * @return \Symfony\Component\DomCrawler\Crawler - */ - protected function crawler() - { - if (! empty($this->subCrawlers)) { - return end($this->subCrawlers); - } - - return $this->crawler; - } - - /** - * Assert the given constraint. - * - * @param \Illuminate\Foundation\Testing\Constraints\PageConstraint $constraint - * @param bool $reverse - * @param string $message - * @return $this - */ - protected function assertInPage(PageConstraint $constraint, $reverse = false, $message = '') - { - if ($reverse) { - $constraint = new ReversePageConstraint($constraint); - } - - self::assertThat( - $this->crawler() ?: $this->response->getContent(), - $constraint, $message - ); - - return $this; - } - - /** - * Assert that a given string is seen on the current HTML. - * - * @param string $text - * @param bool $negate - * @return $this - */ - public function see($text, $negate = false) - { - return $this->assertInPage(new HasSource($text), $negate); - } - - /** - * Assert that a given string is not seen on the current HTML. - * - * @param string $text - * @return $this - */ - public function dontSee($text) - { - return $this->assertInPage(new HasSource($text), true); - } - - /** - * Assert that an element is present on the page. - * - * @param string $selector - * @param array $attributes - * @param bool $negate - * @return $this - */ - public function seeElement($selector, array $attributes = [], $negate = false) - { - return $this->assertInPage(new HasElement($selector, $attributes), $negate); - } - - /** - * Assert that an element is not present on the page. - * - * @param string $selector - * @param array $attributes - * @return $this - */ - public function dontSeeElement($selector, array $attributes = []) - { - return $this->assertInPage(new HasElement($selector, $attributes), true); - } - - /** - * Assert that a given string is seen on the current text. - * - * @param string $text - * @param bool $negate - * @return $this - */ - public function seeText($text, $negate = false) - { - return $this->assertInPage(new HasText($text), $negate); - } - - /** - * Assert that a given string is not seen on the current text. - * - * @param string $text - * @return $this - */ - public function dontSeeText($text) - { - return $this->assertInPage(new HasText($text), true); - } - - /** - * Assert that a given string is seen inside an element. - * - * @param string $element - * @param string $text - * @param bool $negate - * @return $this - */ - public function seeInElement($element, $text, $negate = false) - { - return $this->assertInPage(new HasInElement($element, $text), $negate); - } - - /** - * Assert that a given string is not seen inside an element. - * - * @param string $element - * @param string $text - * @return $this - */ - public function dontSeeInElement($element, $text) - { - return $this->assertInPage(new HasInElement($element, $text), true); - } - - /** - * Assert that a given link is seen on the page. - * - * @param string $text - * @param string|null $url - * @param bool $negate - * @return $this - */ - public function seeLink($text, $url = null, $negate = false) - { - return $this->assertInPage(new HasLink($text, $url), $negate); - } - - /** - * Assert that a given link is not seen on the page. - * - * @param string $text - * @param string|null $url - * @return $this - */ - public function dontSeeLink($text, $url = null) - { - return $this->assertInPage(new HasLink($text, $url), true); - } - - /** - * Assert that an input field contains the given value. - * - * @param string $selector - * @param string $expected - * @param bool $negate - * @return $this - */ - public function seeInField($selector, $expected, $negate = false) - { - return $this->assertInPage(new HasValue($selector, $expected), $negate); - } - - /** - * Assert that an input field does not contain the given value. - * - * @param string $selector - * @param string $value - * @return $this - */ - public function dontSeeInField($selector, $value) - { - return $this->assertInPage(new HasValue($selector, $value), true); - } - - /** - * Assert that the expected value is selected. - * - * @param string $selector - * @param string $value - * @param bool $negate - * @return $this - */ - public function seeIsSelected($selector, $value, $negate = false) - { - return $this->assertInPage(new IsSelected($selector, $value), $negate); - } - - /** - * Assert that the given value is not selected. - * - * @param string $selector - * @param string $value - * @return $this - */ - public function dontSeeIsSelected($selector, $value) - { - return $this->assertInPage(new IsSelected($selector, $value), true); - } - - /** - * Assert that the given checkbox is selected. - * - * @param string $selector - * @param bool $negate - * @return $this - */ - public function seeIsChecked($selector, $negate = false) - { - return $this->assertInPage(new IsChecked($selector), $negate); - } - - /** - * Assert that the given checkbox is not selected. - * - * @param string $selector - * @return $this - */ - public function dontSeeIsChecked($selector) - { - return $this->assertInPage(new IsChecked($selector), true); - } - - /** - * Click a link with the given body, name, or ID attribute. - * - * @param string $name - * @return $this - * - * @throws \InvalidArgumentException - */ - protected function click($name) - { - $link = $this->crawler()->selectLink($name); - - if (! count($link)) { - $link = $this->filterByNameOrId($name, 'a'); - - if (! count($link)) { - throw new InvalidArgumentException( - "Could not find a link with a body, name, or ID attribute of [{$name}]." - ); - } - } - - $this->visit($link->link()->getUri()); - - return $this; - } - - /** - * Fill an input field with the given text. - * - * @param string $text - * @param string $element - * @return $this - */ - protected function type($text, $element) - { - return $this->storeInput($element, $text); - } - - /** - * Check a checkbox on the page. - * - * @param string $element - * @return $this - */ - protected function check($element) - { - return $this->storeInput($element, true); - } - - /** - * Uncheck a checkbox on the page. - * - * @param string $element - * @return $this - */ - protected function uncheck($element) - { - return $this->storeInput($element, false); - } - - /** - * Select an option from a drop-down. - * - * @param string $option - * @param string $element - * @return $this - */ - protected function select($option, $element) - { - return $this->storeInput($element, $option); - } - - /** - * Attach a file to a form field on the page. - * - * @param string $absolutePath - * @param string $element - * @return $this - */ - protected function attach($absolutePath, $element) - { - $this->uploads[$element] = $absolutePath; - - return $this->storeInput($element, $absolutePath); - } - - /** - * Submit a form using the button with the given text value. - * - * @param string $buttonText - * @return $this - */ - protected function press($buttonText) - { - return $this->submitForm($buttonText, $this->inputs, $this->uploads); - } - - /** - * Submit a form on the page with the given input. - * - * @param string $buttonText - * @param array $inputs - * @param array $uploads - * @return $this - */ - protected function submitForm($buttonText, $inputs = [], $uploads = []) - { - $this->makeRequestUsingForm($this->fillForm($buttonText, $inputs), $uploads); - - return $this; - } - - /** - * Fill the form with the given data. - * - * @param string $buttonText - * @param array $inputs - * @return \Symfony\Component\DomCrawler\Form - */ - protected function fillForm($buttonText, $inputs = []) - { - if (! is_string($buttonText)) { - $inputs = $buttonText; - - $buttonText = null; - } - - return $this->getForm($buttonText)->setValues($inputs); - } - - /** - * Get the form from the page with the given submit button text. - * - * @param string|null $buttonText - * @return \Symfony\Component\DomCrawler\Form - * - * @throws \InvalidArgumentException - */ - protected function getForm($buttonText = null) - { - try { - if ($buttonText) { - return $this->crawler()->selectButton($buttonText)->form(); - } - - return $this->crawler()->filter('form')->form(); - } catch (InvalidArgumentException $e) { - throw new InvalidArgumentException( - "Could not find a form that has submit button [{$buttonText}]." - ); - } - } - - /** - * Store a form input in the local array. - * - * @param string $element - * @param string $text - * @return $this - */ - protected function storeInput($element, $text) - { - $this->assertFilterProducesResults($element); - - $element = str_replace(['#', '[]'], '', $element); - - $this->inputs[$element] = $text; - - return $this; - } - - /** - * Assert that a filtered Crawler returns nodes. - * - * @param string $filter - * @return $this - * - * @throws \InvalidArgumentException - */ - protected function assertFilterProducesResults($filter) - { - $crawler = $this->filterByNameOrId($filter); - - if (! count($crawler)) { - throw new InvalidArgumentException( - "Nothing matched the filter [{$filter}] CSS query provided for [{$this->currentUri}]." - ); - } - - return $this; - } - - /** - * Filter elements according to the given name or ID attribute. - * - * @param string $name - * @param array|string $elements - * @return \Symfony\Component\DomCrawler\Crawler - */ - protected function filterByNameOrId($name, $elements = '*') - { - $name = str_replace('#', '', $name); - - $id = str_replace(['[', ']'], ['\\[', '\\]'], $name); - - $elements = is_array($elements) ? $elements : [$elements]; - - array_walk($elements, function (&$element) use ($name, $id) { - $element = "{$element}#{$id}, {$element}[name='{$name}']"; - }); - - return $this->crawler()->filter(implode(', ', $elements)); - } - - /** - * Convert the given uploads to UploadedFile instances. - * - * @param \Symfony\Component\DomCrawler\Form $form - * @param array $uploads - * @return array - */ - protected function convertUploadsForTesting(Form $form, array $uploads) - { - $files = $form->getFiles(); - - $names = array_keys($files); - - $files = array_map(function (array $file, $name) use ($uploads) { - return isset($uploads[$name]) - ? $this->getUploadedFileForTesting($file, $uploads, $name) - : $file; - }, $files, $names); - - $uploads = array_combine($names, $files); - - foreach ($uploads as $key => $file) { - if (preg_match('/.*?(?:\[.*?\])+/', $key)) { - $this->prepareArrayBasedFileInput($uploads, $key, $file); - } - } - - return $uploads; - } - - /** - * Store an array based file upload with the proper nested array structure. - * - * @param array $uploads - * @param string $key - * @param mixed $file - */ - protected function prepareArrayBasedFileInput(&$uploads, $key, $file) - { - preg_match_all('/([^\[\]]+)/', $key, $segments); - - $segments = array_reverse($segments[1]); - - $newKey = array_pop($segments); - - foreach ($segments as $segment) { - $file = [$segment => $file]; - } - - $uploads[$newKey] = $file; - - unset($uploads[$key]); - } - - /** - * Create an UploadedFile instance for testing. - * - * @param array $file - * @param array $uploads - * @param string $name - * @return \Illuminate\Http\UploadedFile - */ - protected function getUploadedFileForTesting($file, $uploads, $name) - { - return new UploadedFile( - $file['tmp_name'], basename($uploads[$name]), $file['type'], $file['size'], $file['error'], true - ); - } -} diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithSession.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithSession.php deleted file mode 100644 index eeb9761b0e2a..000000000000 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithSession.php +++ /dev/null @@ -1,178 +0,0 @@ -session($data); - - return $this; - } - - /** - * Set the session to the given array. - * - * @param array $data - * @return $this - */ - public function session(array $data) - { - $this->startSession(); - - foreach ($data as $key => $value) { - $this->app['session']->put($key, $value); - } - - return $this; - } - - /** - * Start the session for the application. - * - * @return $this - */ - protected function startSession() - { - if (! $this->app['session']->isStarted()) { - $this->app['session']->start(); - } - - return $this; - } - - /** - * Flush all of the current session data. - * - * @return $this - */ - public function flushSession() - { - $this->startSession(); - - $this->app['session']->flush(); - - return $this; - } - - /** - * Assert that the session has a given value. - * - * @param string|array $key - * @param mixed $value - * @return $this - */ - public function seeInSession($key, $value = null) - { - $this->assertSessionHas($key, $value); - - return $this; - } - - /** - * Assert that the session has a given value. - * - * @param string|array $key - * @param mixed $value - * @return $this - */ - public function assertSessionHas($key, $value = null) - { - if (is_array($key)) { - return $this->assertSessionHasAll($key); - } - - if (is_null($value)) { - PHPUnit::assertTrue($this->app['session.store']->has($key), "Session missing key: $key"); - } else { - PHPUnit::assertEquals($value, $this->app['session.store']->get($key)); - } - - return $this; - } - - /** - * Assert that the session has a given list of values. - * - * @param array $bindings - * @return $this - */ - public function assertSessionHasAll(array $bindings) - { - foreach ($bindings as $key => $value) { - if (is_int($key)) { - $this->assertSessionHas($value); - } else { - $this->assertSessionHas($key, $value); - } - } - - return $this; - } - - /** - * Assert that the session does not have a given key. - * - * @param string|array $key - * @return $this - */ - public function assertSessionMissing($key) - { - if (is_array($key)) { - foreach ($key as $k) { - $this->assertSessionMissing($k); - } - } else { - PHPUnit::assertFalse($this->app['session.store']->has($key), "Session has unexpected key: $key"); - } - - return $this; - } - - /** - * Assert that the session has errors bound. - * - * @param string|array $bindings - * @param mixed $format - * @return $this - */ - public function assertSessionHasErrors($bindings = [], $format = null) - { - $this->assertSessionHas('errors'); - - $bindings = (array) $bindings; - - $errors = $this->app['session.store']->get('errors'); - - foreach ($bindings as $key => $value) { - if (is_int($key)) { - PHPUnit::assertTrue($errors->has($value), "Session missing error: $value"); - } else { - PHPUnit::assertContains($value, $errors->get($key, $format)); - } - } - - return $this; - } - - /** - * Assert that the session has old input. - * - * @return $this - */ - public function assertHasOldInput() - { - $this->assertSessionHas('_old_input'); - - return $this; - } -} diff --git a/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php b/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php index 6653157174db..779aa184a00e 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php +++ b/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php @@ -2,35 +2,15 @@ namespace Illuminate\Foundation\Testing\Concerns; -use Closure; -use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Http\Request; -use Illuminate\Http\UploadedFile; -use Illuminate\Contracts\View\View; -use PHPUnit_Framework_Assert as PHPUnit; -use PHPUnit_Framework_ExpectationFailedException; +use Illuminate\Foundation\Testing\TestResponse; +use Illuminate\Contracts\Http\Kernel as HttpKernel; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyUploadedFile; trait MakesHttpRequests { - use InteractsWithPages; - - /** - * The last response returned by the application. - * - * @var \Illuminate\Http\Response - */ - protected $response; - - /** - * The current URL being viewed. - * - * @var string - */ - protected $currentUri; - /** * Additional server variables for the request. * @@ -39,66 +19,30 @@ trait MakesHttpRequests protected $serverVariables = []; /** - * Disable middleware for the test. + * Define a set of server variables to be sent with the requests. * + * @param array $server * @return $this */ - public function withoutMiddleware() + protected function withServerVariables(array $server) { - $this->app->instance('middleware.disable', true); + $this->serverVariables = $server; return $this; } /** - * Visit the given URI with a JSON request. + * Disable middleware for the test. * - * @param string $method - * @param string $uri - * @param array $data - * @param array $headers * @return $this */ - public function json($method, $uri, array $data = [], array $headers = []) + public function withoutMiddleware() { - $files = $this->extractFilesFromDataArray($data); - - $content = json_encode($data); - - $headers = array_merge([ - 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), - 'CONTENT_TYPE' => 'application/json', - 'Accept' => 'application/json', - ], $headers); - - $this->call( - $method, $uri, [], [], $files, $this->transformHeadersToServerVars($headers), $content - ); + $this->app->instance('middleware.disable', true); return $this; } - /** - * Extract the file uploads from the given data array. - * - * @param array $data - * @return array - */ - protected function extractFilesFromDataArray(&$data) - { - $files = []; - - foreach ($data as $key => $value) { - if ($value instanceof SymfonyUploadedFile) { - $files[$key] = $value; - - unset($data[$key]); - } - } - - return $files; - } - /** * Visit the given URI with a GET request. * @@ -110,9 +54,7 @@ public function get($uri, array $headers = []) { $server = $this->transformHeadersToServerVars($headers); - $this->call('GET', $uri, [], [], [], $server); - - return $this; + return $this->call('GET', $uri, [], [], [], $server); } /** @@ -139,9 +81,7 @@ public function post($uri, array $data = [], array $headers = []) { $server = $this->transformHeadersToServerVars($headers); - $this->call('POST', $uri, $data, [], [], $server); - - return $this; + return $this->call('POST', $uri, $data, [], [], $server); } /** @@ -169,9 +109,7 @@ public function put($uri, array $data = [], array $headers = []) { $server = $this->transformHeadersToServerVars($headers); - $this->call('PUT', $uri, $data, [], [], $server); - - return $this; + return $this->call('PUT', $uri, $data, [], [], $server); } /** @@ -199,9 +137,7 @@ public function patch($uri, array $data = [], array $headers = []) { $server = $this->transformHeadersToServerVars($headers); - $this->call('PATCH', $uri, $data, [], [], $server); - - return $this; + return $this->call('PATCH', $uri, $data, [], [], $server); } /** @@ -229,9 +165,7 @@ public function delete($uri, array $data = [], array $headers = []) { $server = $this->transformHeadersToServerVars($headers); - $this->call('DELETE', $uri, $data, [], [], $server); - - return $this; + return $this->call('DELETE', $uri, $data, [], [], $server); } /** @@ -248,310 +182,33 @@ public function deleteJson($uri, array $data = [], array $headers = []) } /** - * Send the given request through the application. - * - * This method allows you to fully customize the entire Request object. - * - * @param \Illuminate\Http\Request $request - * @return $this - */ - public function handle(Request $request) - { - $this->currentUri = $request->fullUrl(); - - $this->response = $this->app->prepareResponse($this->app->handle($request)); - - return $this; - } - - /** - * Assert that the response contains JSON. - * - * @param array|null $data - * @return $this - */ - protected function shouldReturnJson(array $data = null) - { - return $this->receiveJson($data); - } - - /** - * Assert that the response contains JSON. - * - * @param array|null $data - * @return $this|null - */ - protected function receiveJson(array $data = null) - { - return $this->seeJson($data); - } - - /** - * Assert that the response contains an exact JSON array. - * - * @param array $data - * @return $this - */ - public function seeJsonEquals(array $data) - { - $actual = json_encode(Arr::sortRecursive( - (array) $this->decodeResponseJson() - )); - - $this->assertEquals(json_encode(Arr::sortRecursive($data)), $actual); - - return $this; - } - - /** - * Assert that the response contains JSON. - * - * @param array|null $data - * @param bool $negate - * @return $this - */ - public function seeJson(array $data = null, $negate = false) - { - if (is_null($data)) { - $this->assertJson( - $this->response->getContent(), "JSON was not returned from [{$this->currentUri}]." - ); - - return $this; - } - - try { - return $this->seeJsonEquals($data); - } catch (PHPUnit_Framework_ExpectationFailedException $e) { - return $this->seeJsonContains($data, $negate); - } - } - - /** - * Assert that the response doesn't contain JSON. - * - * @param array|null $data - * @return $this - */ - public function dontSeeJson(array $data = null) - { - return $this->seeJson($data, true); - } - - /** - * Assert that the JSON response has a given structure. - * - * @param array|null $structure - * @param array|null $responseData - * @return $this - */ - public function seeJsonStructure(array $structure = null, $responseData = null) - { - if (is_null($structure)) { - return $this->seeJson(); - } - - if (is_null($responseData)) { - $responseData = $this->decodeResponseJson(); - } - - foreach ($structure as $key => $value) { - if (is_array($value) && $key === '*') { - $this->assertInternalType('array', $responseData); - - foreach ($responseData as $responseDataItem) { - $this->seeJsonStructure($structure['*'], $responseDataItem); - } - } elseif (is_array($value)) { - $this->assertArrayHasKey($key, $responseData); - $this->seeJsonStructure($structure[$key], $responseData[$key]); - } else { - $this->assertArrayHasKey($value, $responseData); - } - } - - return $this; - } - - /** - * Assert that the response contains the given JSON. - * - * @param array $data - * @param bool $negate - * @return $this - */ - protected function seeJsonContains(array $data, $negate = false) - { - $method = $negate ? 'assertFalse' : 'assertTrue'; - - $actual = json_encode(Arr::sortRecursive( - (array) $this->decodeResponseJson() - )); - - foreach (Arr::sortRecursive($data) as $key => $value) { - $expected = $this->formatToExpectedJson($key, $value); - - $this->{$method}( - Str::contains($actual, $expected), - ($negate ? 'Found unexpected' : 'Unable to find').' JSON fragment'.PHP_EOL."[{$expected}]".PHP_EOL.'within'.PHP_EOL."[{$actual}]." - ); - } - - return $this; - } - - /** - * Assert that the response is a superset of the given JSON. + * Call the given URI with a JSON request. * + * @param string $method + * @param string $uri * @param array $data + * @param array $headers * @return $this */ - protected function seeJsonSubset(array $data) - { - $this->assertArraySubset($data, $this->decodeResponseJson()); - - return $this; - } - - /** - * Validate and return the decoded response JSON. - * - * @return array - */ - protected function decodeResponseJson() - { - $decodedResponse = json_decode($this->response->getContent(), true); - - if (is_null($decodedResponse) || $decodedResponse === false) { - $this->fail('Invalid JSON was returned from the route. Perhaps an exception was thrown?'); - } - - return $decodedResponse; - } - - /** - * Format the given key and value into a JSON string for expectation checks. - * - * @param string $key - * @param mixed $value - * @return string - */ - protected function formatToExpectedJson($key, $value) - { - $expected = json_encode([$key => $value]); - - if (Str::startsWith($expected, '{')) { - $expected = substr($expected, 1); - } - - if (Str::endsWith($expected, '}')) { - $expected = substr($expected, 0, -1); - } - - return trim($expected); - } - - /** - * Asserts that the status code of the response matches the given code. - * - * @param int $status - * @return $this - */ - protected function seeStatusCode($status) - { - $this->assertEquals($status, $this->response->getStatusCode()); - - return $this; - } - - /** - * Asserts that the response contains the given header and equals the optional value. - * - * @param string $headerName - * @param mixed $value - * @return $this - */ - protected function seeHeader($headerName, $value = null) - { - $headers = $this->response->headers; - - $this->assertTrue($headers->has($headerName), "Header [{$headerName}] not present on response."); - - if (! is_null($value)) { - $this->assertEquals( - $headers->get($headerName), $value, - "Header [{$headerName}] was found, but value [{$headers->get($headerName)}] does not match [{$value}]." - ); - } - - return $this; - } - - /** - * Asserts that the response contains the given cookie and equals the optional value. - * - * @param string $cookieName - * @param mixed $value - * @return $this - */ - protected function seePlainCookie($cookieName, $value = null) - { - return $this->seeCookie($cookieName, $value, false); - } - - /** - * Asserts that the response contains the given cookie and equals the optional value. - * - * @param string $cookieName - * @param mixed $value - * @param bool $encrypted - * @return $this - */ - protected function seeCookie($cookieName, $value = null, $encrypted = true) + public function json($method, $uri, array $data = [], array $headers = []) { - $headers = $this->response->headers; - - $exist = false; - - foreach ($headers->getCookies() as $cookie) { - if ($cookie->getName() === $cookieName) { - $exist = true; - break; - } - } - - $this->assertTrue($exist, "Cookie [{$cookieName}] not present on response."); - - if (! $exist || is_null($value)) { - return $this; - } + $files = $this->extractFilesFromDataArray($data); - $cookieValue = $cookie->getValue(); + $content = json_encode($data); - $actual = $encrypted - ? $this->app['encrypter']->decrypt($cookieValue) : $cookieValue; + $headers = array_merge([ + 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), + 'CONTENT_TYPE' => 'application/json', + 'Accept' => 'application/json', + ], $headers); - $this->assertEquals( - $actual, $value, - "Cookie [{$cookieName}] was found, but value [{$actual}] does not match [{$value}]." + $this->call( + $method, $uri, [], [], $files, $this->transformHeadersToServerVars($headers), $content ); return $this; } - /** - * Define a set of server variables to be sent with the requests. - * - * @param array $server - * @return $this - */ - protected function withServerVariables(array $server) - { - $this->serverVariables = $server; - - return $this; - } - /** * Call the given URI and return the Response. * @@ -566,83 +223,22 @@ protected function withServerVariables(array $server) */ public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null) { - $kernel = $this->app->make('Illuminate\Contracts\Http\Kernel'); - - $this->currentUri = $this->prepareUrlForRequest($uri); + $kernel = $this->app->make(HttpKernel::class); - $this->resetPageContext(); + $files = array_merge($files, $this->extractFilesFromDataArray($parameters)); $symfonyRequest = SymfonyRequest::create( - $this->currentUri, $method, $parameters, - $cookies, $this->filterFiles($files), array_replace($this->serverVariables, $server), $content + $this->prepareUrlForRequest($uri), $method, $parameters, + $cookies, $files, array_replace($this->serverVariables, $server), $content ); - $request = Request::createFromBase($symfonyRequest); - - $response = $kernel->handle($request); + $response = $kernel->handle( + $request = Request::createFromBase($symfonyRequest) + ); $kernel->terminate($request, $response); - return $this->response = $response; - } - - /** - * Call the given HTTPS URI and return the Response. - * - * @param string $method - * @param string $uri - * @param array $parameters - * @param array $cookies - * @param array $files - * @param array $server - * @param string $content - * @return \Illuminate\Http\Response - */ - public function callSecure($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null) - { - $uri = $this->app['url']->secure(ltrim($uri, '/')); - - return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); - } - - /** - * Call a controller action and return the Response. - * - * @param string $method - * @param string $action - * @param array $wildcards - * @param array $parameters - * @param array $cookies - * @param array $files - * @param array $server - * @param string $content - * @return \Illuminate\Http\Response - */ - public function action($method, $action, $wildcards = [], $parameters = [], $cookies = [], $files = [], $server = [], $content = null) - { - $uri = $this->app['url']->action($action, $wildcards, true); - - return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); - } - - /** - * Call a named route and return the Response. - * - * @param string $method - * @param string $name - * @param array $routeParameters - * @param array $parameters - * @param array $cookies - * @param array $files - * @param array $server - * @param string $content - * @return \Illuminate\Http\Response - */ - public function route($method, $name, $routeParameters = [], $parameters = [], $cookies = [], $files = [], $server = [], $content = null) - { - $uri = $this->app['url']->route($name, $routeParameters); - - return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); + return $this->createTestResponse($response); } /** @@ -689,186 +285,34 @@ protected function transformHeadersToServerVars(array $headers) } /** - * Filter the given array of files, removing any empty values. + * Extract the file uploads from the given data array. * - * @param array $files - * @return mixed + * @param array $data + * @return array */ - protected function filterFiles($files) + protected function extractFilesFromDataArray(&$data) { - foreach ($files as $key => $file) { - if ($file instanceof UploadedFile) { - continue; - } + $files = []; - if (is_array($file)) { - if (! isset($file['name'])) { - $files[$key] = $this->filterFiles($files[$key]); - } elseif (isset($files[$key]['error']) && $files[$key]['error'] !== 0) { - unset($files[$key]); - } + foreach ($data as $key => $value) { + if ($value instanceof SymfonyUploadedFile) { + $files[$key] = $value; - continue; + unset($data[$key]); } - - unset($files[$key]); } return $files; } /** - * Assert that the client response has an OK status code. + * Create the test response instance from the given response. * - * @return $this + * @param \Illuminate\Http\Response $response + * @return \Illuminate\Foundation\Testing\TestResponse */ - public function assertResponseOk() + protected function createTestResponse($response) { - $actual = $this->response->getStatusCode(); - - PHPUnit::assertTrue($this->response->isOk(), "Expected status code 200, got {$actual}."); - - return $this; - } - - /** - * Assert that the client response has a given code. - * - * @param int $code - * @return $this - */ - public function assertResponseStatus($code) - { - $actual = $this->response->getStatusCode(); - - PHPUnit::assertEquals($code, $this->response->getStatusCode(), "Expected status code {$code}, got {$actual}."); - - return $this; - } - - /** - * Assert that the response view has a given piece of bound data. - * - * @param string|array $key - * @param mixed $value - * @return $this - */ - public function assertViewHas($key, $value = null) - { - if (is_array($key)) { - return $this->assertViewHasAll($key); - } - - if (! isset($this->response->original) || ! $this->response->original instanceof View) { - return PHPUnit::assertTrue(false, 'The response was not a view.'); - } - - if (is_null($value)) { - PHPUnit::assertArrayHasKey($key, $this->response->original->getData()); - } elseif ($value instanceof Closure) { - PHPUnit::assertTrue($value($this->response->original->$key)); - } else { - PHPUnit::assertEquals($value, $this->response->original->$key); - } - - return $this; - } - - /** - * Assert that the view has a given list of bound data. - * - * @param array $bindings - * @return $this - */ - public function assertViewHasAll(array $bindings) - { - foreach ($bindings as $key => $value) { - if (is_int($key)) { - $this->assertViewHas($value); - } else { - $this->assertViewHas($key, $value); - } - } - - return $this; - } - - /** - * Assert that the response view is missing a piece of bound data. - * - * @param string $key - * @return $this - */ - public function assertViewMissing($key) - { - if (! isset($this->response->original) || ! $this->response->original instanceof View) { - return PHPUnit::assertTrue(false, 'The response was not a view.'); - } - - PHPUnit::assertArrayNotHasKey($key, $this->response->original->getData()); - - return $this; - } - - /** - * Assert whether the client was redirected to a given URI. - * - * @param string $uri - * @param array $with - * @return $this - */ - public function assertRedirectedTo($uri, $with = []) - { - PHPUnit::assertInstanceOf('Illuminate\Http\RedirectResponse', $this->response); - - PHPUnit::assertEquals($this->app['url']->to($uri), $this->response->headers->get('Location')); - - $this->assertSessionHasAll($with); - - return $this; - } - - /** - * Assert whether the client was redirected to a given route. - * - * @param string $name - * @param array $parameters - * @param array $with - * @return $this - */ - public function assertRedirectedToRoute($name, $parameters = [], $with = []) - { - return $this->assertRedirectedTo($this->app['url']->route($name, $parameters), $with); - } - - /** - * Assert whether the client was redirected to a given action. - * - * @param string $name - * @param array $parameters - * @param array $with - * @return $this - */ - public function assertRedirectedToAction($name, $parameters = [], $with = []) - { - return $this->assertRedirectedTo($this->app['url']->action($name, $parameters), $with); - } - - /** - * Dump the content from the last response. - * - * @return void - */ - public function dump() - { - $content = $this->response->getContent(); - - $json = json_decode($content); - - if (json_last_error() === JSON_ERROR_NONE) { - $content = $json; - } - - dd($content); + return TestResponse::fromBaseResponse($response); } } diff --git a/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php b/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php index 8ee4ab5b3a42..26e947e31cec 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php +++ b/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php @@ -109,127 +109,6 @@ protected function withoutEvents() return $this; } - /** - * Specify a list of events that should be fired for the given operation. - * - * These events will be mocked, so that handlers will not actually be executed. - * - * @param string $model - * @param array|string $events - * @return $this - * - * @throws \Exception - */ - public function expectsModelEvents($model, $events) - { - $events = $this->formatModelEvents($model, $events); - - $this->withoutModelEvents(); - - $this->beforeApplicationDestroyed(function () use ($events) { - $fired = $this->getFiredModelEvents($events); - - if ($eventsNotFired = array_diff($events, $fired)) { - throw new Exception( - 'These expected Eloquent events were not fired: ['.implode(', ', $eventsNotFired).']' - ); - } - }); - - return $this; - } - - /** - * Specify a list of events that should not be fired for the given operation. - * - * These events will be mocked, so that handlers will not actually be executed. - * - * @param string $model - * @param array|string $events - * @return $this - * - * @throws \Exception - */ - public function doesntExpectModelEvents($model, $events) - { - $events = $this->formatModelEvents($model, $events); - - $this->withoutModelEvents(); - - $this->beforeApplicationDestroyed(function () use ($events) { - if ($fired = $this->getFiredModelEvents($events)) { - throw new Exception( - 'These unexpected Eloquent events were fired: ['.implode(', ', $fired).']' - ); - } - }); - - return $this; - } - - /** - * Convert a model and a list of events into the Eloquent's format. - * - * @param string $model - * @param array|string $events - * @return string[] - */ - private function formatModelEvents($model, $events) - { - $events = (array) $events; - - return array_map(function ($event) use ($model) { - return "eloquent.{$event}: {$model}"; - }, (array) $events); - } - - /** - * Mock the model event dispatcher so all Eloquent events are silenced. - * - * @return $this - */ - protected function withoutModelEvents() - { - $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher'); - - $mock->shouldReceive('fire')->andReturnUsing(function ($called) { - $this->firedModelEvents[] = $called; - }); - - $mock->shouldReceive('until')->andReturnUsing(function ($called) { - $this->firedModelEvents[] = $called; - - return true; - }); - - $mock->shouldReceive('listen')->andReturnUsing(function ($event, $listener, $priority) { - // - }); - - Model::setEventDispatcher($mock); - - return $this; - } - - /** - * Specify a list of observers that will not run for the given operation. - * - * @param array|string $observers - * @return $this - */ - public function withoutObservers($observers) - { - $observers = is_array($observers) ? $observers : [$observers]; - - array_map(function ($observer) { - $this->app->bind($observer, function () use ($observer) { - return $this->getMockBuilder($observer)->disableOriginalConstructor()->getMock(); - }); - }, $observers); - - return $this; - } - /** * Filter the given events against the fired events. * @@ -241,17 +120,6 @@ protected function getFiredEvents(array $events) return $this->getDispatched($events, $this->firedEvents); } - /** - * Filter the given events against the fired events. - * - * @param array $events - * @return array - */ - protected function getFiredModelEvents(array $events) - { - return $this->getDispatched($events, $this->firedModelEvents); - } - /** * Specify a list of jobs that should be dispatched for the given operation. * diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index 26e2540e9b8a..29da5586f2d6 100755 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -11,11 +11,9 @@ abstract class TestCase extends PHPUnit_Framework_TestCase { use Concerns\InteractsWithContainer, Concerns\MakesHttpRequests, - Concerns\ImpersonatesUsers, Concerns\InteractsWithAuthentication, Concerns\InteractsWithConsole, Concerns\InteractsWithDatabase, - Concerns\InteractsWithSession, Concerns\MocksApplicationServices; /** diff --git a/src/Illuminate/Foundation/Testing/TestResponse.php b/src/Illuminate/Foundation/Testing/TestResponse.php new file mode 100644 index 000000000000..2fa7143207d4 --- /dev/null +++ b/src/Illuminate/Foundation/Testing/TestResponse.php @@ -0,0 +1,320 @@ +getContent(), $response->status() + ); + + $testResponse->headers = $response->headers; + + if (isset($response->original)) { + $testResponse->original = $response->original; + } + + if (isset($response->exception)) { + $testResponse->exception = $response->exception; + } + + return $testResponse; + } + + /** + * Assert that the response has an OK status code. + * + * @return void + */ + public function assertHasStatus($status) + { + $actual = $this->getStatusCode(); + + PHPUnit::assertTrue($this->isOk(), "Expected status code 200, got {$actual}."); + } + + /** + * Assert whether the response is redirecting to a given URI. + * + * @param string $uri + * @return void + */ + public function assertIsRedirect($uri) + { + PHPUnit::assertTrue( + $this->isRedirect(), 'Response status code ['.$this->status().'] is not a redirect status code.' + ); + + PHPUnit::assertEquals(app('url')->to($uri), $this->headers->get('Location')); + } + + /** + * Asserts that the response contains the given header and equals the optional value. + * + * @param string $headerName + * @param mixed $value + * @return $this + */ + public function assertHasHeader($headerName, $value = null) + { + PHPUnit::assertTrue( + $this->headers->has($headerName), "Header [{$headerName}] not present on response." + ); + + $actual = $this->headers->get($headerName); + + if (! is_null($value)) { + PHPUnit::assertEquals( + $this->headers->get($headerName), $value, + "Header [{$headerName}] was found, but value [{$actual}] does not match [{$value}]." + ); + } + + return $this; + } + + /** + * Asserts that the response contains the given cookie and equals the optional value. + * + * @param string $cookieName + * @param mixed $value + * @return void + */ + public function assertHasPlainCookie($cookieName, $value = null) + { + $this->seeCookie($cookieName, $value, false); + } + + /** + * Asserts that the response contains the given cookie and equals the optional value. + * + * @param string $cookieName + * @param mixed $value + * @param bool $encrypted + * @return void + */ + public function assertHasCookie($cookieName, $value = null, $encrypted = true) + { + $headers = $this->headers; + + $exist = false; + + foreach ($headers->getCookies() as $cookie) { + if ($cookie->getName() === $cookieName) { + $exist = true; + break; + } + } + + PHPUnit::assertTrue($exist, "Cookie [{$cookieName}] not present on response."); + + if (! $exist || is_null($value)) { + return $this; + } + + $cookieValue = $cookie->getValue(); + + $actual = $encrypted + ? app('encrypter')->decrypt($cookieValue) : $cookieValue; + + PHPUnit::assertEquals( + $actual, $value, + "Cookie [{$cookieName}] was found, but value [{$actual}] does not match [{$value}]." + ); + } + + /** + * Assert that the response is a superset of the given JSON. + * + * @param array $data + * @return void + */ + public function assertHasJson(array $data) + { + PHPUnit::assertArraySubset($data, $this->decodeResponseJson()); + } + + /** + * Validate and return the decoded response JSON. + * + * @return array + */ + protected function decodeResponseJson() + { + $decodedResponse = json_decode($this->getContent(), true); + + if (is_null($decodedResponse) || $decodedResponse === false) { + if ($this->exception) { + throw $this->exception; + } else { + PHPUnit::fail('Invalid JSON was returned from the route.'); + } + } + + return $decodedResponse; + } + + /** + * Format the given key and value into a JSON string for expectation checks. + * + * @param string $key + * @param mixed $value + * @return string + */ + protected function formatToExpectedJson($key, $value) + { + $expected = json_encode([$key => $value]); + + if (Str::startsWith($expected, '{')) { + $expected = substr($expected, 1); + } + + if (Str::endsWith($expected, '}')) { + $expected = substr($expected, 0, -1); + } + + return trim($expected); + } + + /** + * Assert that the response view has a given piece of bound data. + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function assertViewHas($key, $value = null) + { + if (is_array($key)) { + return $this->assertViewHasAll($key); + } + + if (! isset($this->original) || ! $this->original instanceof View) { + return PHPUnit::assertTrue(false, 'The response is not a view.'); + } + + if (is_null($value)) { + PHPUnit::assertArrayHasKey($key, $this->original->getData()); + } elseif ($value instanceof Closure) { + PHPUnit::assertTrue($value($this->original->$key)); + } else { + PHPUnit::assertEquals($value, $this->original->$key); + } + } + + /** + * Assert that the response view has a given list of bound data. + * + * @param array $bindings + * @return void + */ + public function assertViewHasAll(array $bindings) + { + foreach ($bindings as $key => $value) { + if (is_int($key)) { + $this->assertViewHas($value); + } else { + $this->assertViewHas($key, $value); + } + } + } + + /** + * Assert that the response view is missing a piece of bound data. + * + * @param string $key + * @return void + */ + public function assertViewMissing($key) + { + if (! isset($this->original) || ! $this->original instanceof View) { + return PHPUnit::fail('The response is not a view.'); + } + + PHPUnit::assertArrayNotHasKey($key, $this->original->getData()); + } + + /** + * Assert that the session has a given value. + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function assertSessionHas($key, $value = null) + { + if (is_array($key)) { + return $this->assertSessionHasAll($key); + } + + if (is_null($value)) { + PHPUnit::assertTrue( + $this->session()->has($key), + "Session is missing expected key [{$key}]." + ); + } else { + PHPUnit::assertEquals($value, app('session.store')->get($key)); + } + } + + /** + * Assert that the session has a given list of values. + * + * @param array $bindings + * @return void + */ + public function assertSessionHasAll(array $bindings) + { + foreach ($bindings as $key => $value) { + if (is_int($key)) { + $this->assertSessionHas($value); + } else { + $this->assertSessionHas($key, $value); + } + } + } + + /** + * Assert that the session does not have a given key. + * + * @param string|array $key + * @return void + */ + public function assertSessionMissing($key) + { + if (is_array($key)) { + foreach ($key as $value) { + $this->assertSessionMissing($value); + } + } else { + PHPUnit::assertFalse( + $this->session()->has($key), + "Session has unexpected key [{$key}]." + ); + } + } + + /** + * Get the current session store. + * + * @return \Illuminate\Session\Store + */ + protected function session() + { + return app('session.store'); + } +} diff --git a/tests/Foundation/FoundationExpectsModelEventsTest.php b/tests/Foundation/FoundationExpectsModelEventsTest.php deleted file mode 100644 index e6959d074b4e..000000000000 --- a/tests/Foundation/FoundationExpectsModelEventsTest.php +++ /dev/null @@ -1,233 +0,0 @@ -addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - ]); - - $db->bootEloquent(); - $db->setAsGlobal(); - - $this->createSchema(); - - return $app; - } - - /** @test */ - public function a_mock_replaces_the_event_dispatcher_when_calling_expects_model_events() - { - $this->assertInstanceOf(Dispatcher::class, Model::getEventDispatcher()); - - $this->assertNotInstanceOf(Mock::class, Model::getEventDispatcher()); - - $this->expectsModelEvents(EloquentTestModel::class, []); - - $this->assertNotInstanceOf(Dispatcher::class, Model::getEventDispatcher()); - $this->assertInstanceOf(Mock::class, Model::getEventDispatcher()); - } - - /** @test */ - public function a_mock_does_not_carry_over_between_tests() - { - $this->assertInstanceOf(Dispatcher::class, Model::getEventDispatcher()); - - $this->assertNotInstanceOf(Mock::class, Model::getEventDispatcher()); - } - - /** @test */ - public function fired_events_can_be_checked_for() - { - $this->expectsModelEvents(EloquentTestModel::class, [ - 'booting', - 'booted', - - 'creating', - 'created', - - 'saving', - 'saved', - - 'updating', - 'updated', - - 'deleting', - 'deleted', - ]); - - $model = EloquentTestModel::create(['field' => 1]); - $model->field = 2; - $model->save(); - $model->delete(); - } - - /** @test */ - public function using_expects_model_events_multiple_times_works() - { - $this->expectsModelEvents(EloquentTestModel::class, [ - 'booting', - 'booted', - ]); - - $this->expectsModelEvents(EloquentTestModel::class, [ - 'creating', - 'created', - ]); - - $model = EloquentTestModel::create(['field' => 1]); - $model->field = 2; - $model->save(); - $model->delete(); - } - - /** @test */ - public function expects_model_events_can_take_a_string_as_the_event_name() - { - $this->expectsModelEvents(EloquentTestModel::class, 'booting'); - - EloquentTestModel::create(['field' => 1]); - } - - /** @test */ - public function expects_events_fires_on_model_events() - { - EloquentTestModel::created(function () { - event(ExampleEvent::class); - }); - - $this->expectsEvents(ExampleEvent::class); - - EloquentTestModel::create(['field' => 1]); - } - - /** @test */ - public function unfired_events_can_be_checked_for() - { - $this->doesntExpectModelEvents(EloquentTestModel::class, [ - 'updating', - 'updated', - - 'deleting', - 'deleted', - ]); - - EloquentTestModel::create(['field' => 1]); - } - - /** @test */ - public function using_doesnt_expect_model_events_multiple_times_works() - { - $this->doesntExpectModelEvents(EloquentTestModel::class, [ - 'updating', - 'updated', - ]); - - $this->doesntExpectModelEvents(EloquentTestModel::class, [ - 'deleting', - 'deleted', - ]); - - EloquentTestModel::create(['field' => 1]); - } - - /** @test */ - public function doesnt_expect_model_events_can_take_a_string_as_the_event_name() - { - $this->doesntExpectModelEvents(EloquentTestModel::class, 'deleting'); - - EloquentTestModel::create(['field' => 1]); - } - - /** @test */ - public function observers_do_not_fire_when_mocking_events() - { - $this->expectsModelEvents(EloquentTestModel::class, [ - 'saving', - 'saved', - ]); - - $this->doesntExpectModelEvents(EloquentTestModel::class, [ - 'deleting', - 'deleted', - ]); - - EloquentTestModel::observe(new EloquentTestModelFailingObserver); - - EloquentTestModel::create(['field' => 1]); - } - - protected function createSchema() - { - $this->schema('default')->create('test', function ($table) { - $table->increments('id'); - $table->string('field'); - $table->timestamps(); - }); - } - - /** - * Get a database connection instance. - * - * @return Connection - */ - protected function connection($connection = 'default') - { - return Eloquent::getConnectionResolver()->connection($connection); - } - - /** - * Get a schema builder instance. - * - * @return Schema\Builder - */ - protected function schema($connection = 'default') - { - return $this->connection($connection)->getSchemaBuilder(); - } -} - -class EloquentTestModel extends Eloquent -{ - protected $guarded = []; - protected $table = 'test'; -} - -class EloquentTestModelFailingObserver -{ - public function saving() - { - PHPUnit_Framework_Assert::fail('The [saving] method should not be called on '.static::class); - } - - public function saved() - { - PHPUnit_Framework_Assert::fail('The [saved] method should not be called on '.static::class); - } - - public function deleting() - { - PHPUnit_Framework_Assert::fail('The [deleting] method should not be called on '.static::class); - } - - public function deleted() - { - PHPUnit_Framework_Assert::fail('The [deleted] method should not be called on '.static::class); - } -} diff --git a/tests/Foundation/FoundationInteractsWithPagesTest.php b/tests/Foundation/FoundationInteractsWithPagesTest.php deleted file mode 100644 index 74debdf27a6d..000000000000 --- a/tests/Foundation/FoundationInteractsWithPagesTest.php +++ /dev/null @@ -1,471 +0,0 @@ -crawler = new Crawler($html); - } - - public function testSeePageIs() - { - $this->currentUri = 'https://laravel.com/docs'; - - $this->response = m::mock(Response::class); - $this->response->shouldReceive('getStatusCode') - ->once() - ->andReturn(200); - - $this->seePageIs('/docs'); - } - - public function testSeeThroughWebCrawler() - { - $this->setCrawler('

The PHP Framework For Web Artisans

'); - $this->see('Web Artisans'); - } - - public function testSeeThroughResponse() - { - $this->crawler = null; - - $this->response = m::mock(Response::class); - $this->response->shouldReceive('getContent') - ->once() - ->andReturn('

The PHP Framework For Web Artisans

'); - - $this->see('Web Artisans'); - } - - public function testSeeWithSpecialCharacters() - { - $this->setCrawler($this->getHtmlTemplate('(Ver más)')); - - $this->see('(Ver más)'); - } - - public function testDontSee() - { - $this->setCrawler('

The PHP Framework For Web Artisans

'); - $this->dontSee('Webmasters'); - } - - public function testSeeTextAndDontSeeText() - { - $this->setCrawler('

Laravel is a PHP Framework.'); - - // The methods see and dontSee compare against the HTML. - $this->see('strong'); - $this->dontSee('Laravel is a PHP Framework'); - - // seeText and dontSeeText strip the HTML and compare against the plain text. - $this->seeText('Laravel is a PHP Framework.'); - $this->dontSeeText('strong'); - } - - public function testSeeInElement() - { - $this->setCrawler('

Laravel was created by Taylor Otwell
'); - $this->seeInElement('strong', 'Taylor'); - } - - public function testSeeInElementWithSpecialCharacters() - { - $this->setCrawler( - $this->getHtmlTemplate('
Laravel es un framework de código abierto
') - ); - $this->seeInElement('strong', 'código'); - } - - public function testSeeInElementSearchInAllElements() - { - $this->setCrawler( - '
- Laravel is a PHP framework - created by Taylor Otwell -
' - ); - - $this->seeInElement('strong', 'Taylor'); - } - - public function testSeeInElementSearchInHtmlTags() - { - $this->setCrawler( - '
- -
' - ); - - $this->seeInElement('#mytable', 'image.jpg'); - } - - public function testdontSeeInElement() - { - $this->setCrawler( - '
Laravel was created by Taylor Otwell
' - ); - - $this->seeInElement('strong', 'Laravel', true); - $this->dontSeeInElement('strong', 'Laravel'); - } - - public function testSeeLink() - { - $this->setCrawler( - 'Laravel' - ); - - $this->seeLink('Laravel'); - $this->seeLink('Laravel', 'https://laravel.com'); - } - - public function testDontSeeLink() - { - $this->setCrawler( - 'Laravel' - ); - - $this->dontSeeLink('Symfony'); - $this->dontSeeLink('Symfony', 'https://symfonyc.com'); - } - - protected function getInputHtml($name = 'framework', $value = 'Laravel') - { - return sprintf('', $name, $value); - } - - public function testSeeInInput() - { - $this->setCrawler($this->getInputHtml()); - $this->seeInField('framework', 'Laravel'); - } - - public function testDontSeeInInput() - { - $this->setCrawler($this->getInputHtml()); - $this->dontSeeInField('framework', 'Rails'); - $this->dontSeeInField('framework', 'laravel'); - - $this->setCrawler($this->getInputHtml('number', '')); - $this->dontSeeInField('number', '0'); - } - - protected function getInputArrayHtml() - { - return ''; - } - - public function testSeeInInputArray() - { - $this->setCrawler($this->getInputArrayHtml()); - $this->seeInField('framework[]', 'Laravel'); - } - - public function testDontSeeInInputArray() - { - $this->setCrawler($this->getInputArrayHtml()); - $this->dontSeeInField('framework[]', 'Rails'); - } - - protected function getTextareaHtml() - { - return ''; - } - - public function testSeeInTextarea() - { - $this->setCrawler($this->getTextareaHtml()); - $this->seeInField('description', 'Laravel is awesome'); - } - - public function testDontSeeInTextarea() - { - $this->setCrawler($this->getTextareaHtml()); - $this->dontSeeInField('description', 'Rails is awesome'); - } - - protected function getSelectHtml() - { - return - ''; - } - - public function testSeeOptionIsSelected() - { - $this->setCrawler($this->getSelectHtml()); - $this->seeIsSelected('availability', 'full_time'); - } - - public function testDontSeeOptionIsSelected() - { - $this->setCrawler($this->getSelectHtml()); - $this->dontSeeIsSelected('availability', 'partial_time'); - } - - protected function getSelectHtmlWithoutValueAttribute() - { - return - ''; - } - - public function testSeeOptionWithoutValueIsSelected() - { - $this->setCrawler($this->getSelectHtmlWithoutValueAttribute()); - $this->seeIsSelected('size', 'M'); - } - - public function testDontSeeOptionWithoutValueIsSelected() - { - $this->setCrawler($this->getSelectHtmlWithoutValueAttribute()); - $this->dontSeeIsSelected('size', 'S'); - } - - protected function getEmptySelectHtml() - { - return - ''; - } - - public function testDontSeeOptionIsSelectedInEmptySelect() - { - $this->setCrawler($this->getEmptySelectHtml()); - $this->dontSeeIsSelected('category', '0'); - $this->dontSeeIsSelected('category', 0); - } - - protected function getMultipleSelectHtml() - { - return - ''; - } - - public function testSeeMultipleOptionsAreSelected() - { - $this->setCrawler($this->getMultipleSelectHtml()); - $this->seeIsSelected('roles[]', 'user'); - $this->seeIsSelected('roles[]', 'reviewer'); - } - - public function testDontSeeMultipleOptionsAreSelected() - { - $this->setCrawler($this->getMultipleSelectHtml()); - $this->dontSeeIsSelected('roles[]', 'admin'); - $this->dontSeeIsSelected('roles[]', 'journalist'); - } - - protected function getSelectWithOptGroupHtml() - { - return - ''; - } - - public function testSeeOptionInOptgroupIsSelected() - { - $this->setCrawler($this->getSelectWithOptGroupHtml()); - $this->seeIsSelected('technology', 'laravel'); - } - - public function testDontseeOptionInOptgroupIsSelected() - { - $this->setCrawler($this->getSelectWithOptGroupHtml()); - $this->dontSeeIsSelected('technology', 'symfony'); - } - - protected function getSelectMultipleWithOptGroupHtml() - { - return - ''; - } - - public function testSeeOptionsInOptgroupAreSelected() - { - $this->setCrawler($this->getSelectMultipleWithOptGroupHtml()); - $this->seeIsSelected('technologies[]', 'laravel'); - $this->seeIsSelected('technologies[]', 'vue'); - } - - public function testDontseeOptionsInOptgroupAreSelected() - { - $this->setCrawler($this->getSelectMultipleWithOptGroupHtml()); - $this->dontSeeIsSelected('technologies[]', 'symfony'); - $this->dontSeeIsSelected('technologies[]', 'angular'); - } - - protected function getRadiosHtml() - { - return - '' - .''; - } - - public function testSeeRadioIsChecked() - { - $this->setCrawler($this->getRadiosHtml()); - $this->seeIsSelected('availability', 'full_time'); - } - - public function testDontSeeRadioIsChecked() - { - $this->setCrawler($this->getRadiosHtml()); - $this->dontSeeIsSelected('availability', 'partial_time'); - } - - protected function getCheckboxesHtml() - { - return - ' - '; - } - - public function testSeeCheckboxIsChecked() - { - $this->setCrawler($this->getCheckboxesHtml()); - $this->seeIsChecked('terms'); - } - - public function testDontSeeCheckboxIsChecked() - { - $this->setCrawler($this->getCheckboxesHtml()); - $this->dontSeeIsChecked('list'); - } - - public function testSeeElement() - { - $this->setCrawler(''); - $this->seeElement('image'); - } - - public function testSeeElementWithAttributes() - { - $this->setCrawler(''); - $this->seeElement('image', ['width' => 100, 'height' => 50]); - - $this->setCrawler(''); - $this->seeElement('#name', ['required']); - } - - public function testDontSeeElement() - { - $this->setCrawler(''); - $this->dontSeeElement('iframe'); - $this->dontSeeElement('image', ['id']); - $this->dontSeeElement('image', ['class' => 'video']); - - $this->setCrawler(''); - $this->dontSeeElement('textarea'); - $this->dontSeeElement('input', ['required']); - } - - protected function getLayoutHtml() - { - return - '
-

Laravel

-
-
-

The PHP Framework For Web Artisans

-

Elegant applications delivered at warp speed.

-
- '; - } - - public function testWithin() - { - $this->setCrawler($this->getLayoutHtml()); - - // Limit the search to the "header" area - $this->within('header', function () { - $this->see('Laravel') - ->dontSeeInElement('h2', 'PHP Framework'); - }); - - // Make sure we are out of the within context - $this->seeLink('Documentation'); - - // Test other methods as well - $this->within('#features', function () { - $this->seeInElement('h2', 'PHP Framework') - ->dontSee('Laravel') - ->dontSeeLink('Documentation'); - }); - } - - public function testNestedWithin() - { - $this->setCrawler($this->getLayoutHtml()); - - $this->within('#features', function () { - $this->dontSee('Laravel') - ->see('Web Artisans') - ->within('h2', function () { - $this->see('PHP Framework') - ->dontSee('Elegant applications'); - }); - }); - } - - /** - * Make sure that the HTML will be encoded as UTF-8 by the Symfony crawler. - * - * @param string $content - * @return string - */ - protected function getHtmlTemplate($content) - { - return ' - - - - - '.$content.' - '; - } -} diff --git a/tests/Foundation/FoundationInteractsWithPagesUnitTest.php b/tests/Foundation/FoundationInteractsWithPagesUnitTest.php deleted file mode 100644 index bac45a5f0d36..000000000000 --- a/tests/Foundation/FoundationInteractsWithPagesUnitTest.php +++ /dev/null @@ -1,170 +0,0 @@ -crawler = m::mock(Crawler::class)->makePartial(); - } - - public function tearDown() - { - m::close(); - } - - protected function mockInput($value) - { - $input = m::mock(Crawler::class)->makePartial(); - $input->shouldReceive('count')->andReturn(1); - $input->shouldReceive('nodeName')->once()->andReturn('input'); - $input->shouldReceive('attr') - ->withArgs(['value']) - ->once() - ->andReturn($value); - - return $input; - } - - public function testSeeInFieldInput() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#framework, input[name='framework'], textarea#framework, textarea[name='framework']"]) - ->once() - ->andReturn($this->mockInput('Laravel')); - - $this->seeInField('framework', 'Laravel'); - } - - public function testDontSeeInFieldInput() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#framework, input[name='framework'], textarea#framework, textarea[name='framework']"]) - ->once() - ->andReturn($this->mockInput('Laravel')); - - $this->dontSeeInField('framework', 'Rails'); - } - - public function testSeeInFieldInputArray() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#framework\\[\\], input[name='framework[]'], textarea#framework\\[\\], textarea[name='framework[]']"]) - ->once() - ->andReturn($this->mockInput('Laravel')); - - $this->seeInField('framework[]', 'Laravel'); - } - - public function testDontSeeInFieldInputArray() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#framework\\[\\], input[name='framework[]'], textarea#framework\\[\\], textarea[name='framework[]']"]) - ->once() - ->andReturn($this->mockInput('Laravel')); - - $this->dontSeeInField('framework[]', 'Rails'); - } - - protected function mockTextarea($value) - { - $textarea = m::mock(Crawler::class)->makePartial(); - $textarea->shouldReceive('count')->andReturn(1); - $textarea->shouldReceive('nodeName')->once()->andReturn('textarea'); - $textarea->shouldReceive('text')->once()->andReturn($value); - - return $textarea; - } - - public function testSeeInFieldTextarea() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#description, input[name='description'], textarea#description, textarea[name='description']"]) - ->once() - ->andReturn($this->mockTextarea('Laravel is awesome')); - - $this->seeInField('description', 'Laravel is awesome'); - } - - public function testDontSeeInFieldTextarea() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input#description, input[name='description'], textarea#description, textarea[name='description']"]) - ->once() - ->andReturn($this->mockTextarea('Laravel is awesome')); - - $this->dontSeeInField('description', 'Rails is awesome'); - } - - /** - * @expectedException \PHPUnit_Framework_ExpectationFailedException - * @expectedExceptionMessage Failed asserting that the field [select] contains the expected value [selected_value]: There is no input,textarea with the name or ID [select]. - */ - public function testSeeInFieldWrongElementException() - { - $node = m::mock(Crawler::class)->makePartial(); - $node->shouldReceive('count')->andReturn(0); - - $this->crawler->shouldReceive('filter') - ->withArgs(["input#select, input[name='select'], textarea#select, textarea[name='select']"]) - ->once() - ->andReturn($node); - - $this->crawler->shouldReceive('html') - ->once() - ->andReturn(''); - - $this->seeInField('select', 'selected_value'); - } - - protected function mockCheckbox($checked = true) - { - $checkbox = m::mock(Crawler::class)->makePartial(); - $checkbox->shouldReceive('count')->andReturn(1); - $checkbox->shouldReceive('attr') - ->withArgs(['checked']) - ->once() - ->andReturn($checked ? 'checked' : null); - - return $checkbox; - } - - public function testSeeIsChecked() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input[type='checkbox']#terms, input[type='checkbox'][name='terms']"]) - ->once() - ->andReturn($this->mockCheckbox(true)); - - $this->seeIsChecked('terms'); - } - - public function testDontSeeIsChecked() - { - $this->crawler->shouldReceive('filter') - ->withArgs(["input[type='checkbox']#terms, input[type='checkbox'][name='terms']"]) - ->once() - ->andReturn($this->mockCheckbox(false)); - - $this->dontSeeIsChecked('terms'); - } - - public function testExtractsRequestParametersFromForm() - { - $form = m::mock('Symfony\Component\DomCrawler\Form'); - - $form->shouldReceive('getValues')->once()->andReturn([]); - $this->assertEquals([], $this->extractParametersFromForm($form)); - - $form->shouldReceive('getValues')->once()->andReturn(['name' => 'Laravel', 'license' => 'MIT']); - $this->assertEquals(['name' => 'Laravel', 'license' => 'MIT'], $this->extractParametersFromForm($form)); - - $form->shouldReceive('getValues')->once()->andReturn(['name' => 'Laravel', 'keywords[0]' => 'framework', 'keywords[1]' => 'laravel']); - $this->assertEquals(['name' => 'Laravel', 'keywords' => ['framework', 'laravel']], $this->extractParametersFromForm($form)); - } -} diff --git a/tests/Foundation/FoundationMakesHttpRequestsJsonTest.php b/tests/Foundation/FoundationMakesHttpRequestsJsonTest.php deleted file mode 100644 index 9fd5d6785115..000000000000 --- a/tests/Foundation/FoundationMakesHttpRequestsJsonTest.php +++ /dev/null @@ -1,127 +0,0 @@ -response = new Illuminate\Http\Response(new JsonSerializableSingleResourceStub); - - $resource = new JsonSerializableSingleResourceStub; - - $this->seeJson($resource->jsonSerialize()); - } - - public function testSeeJsonWithMixed() - { - $this->response = new Illuminate\Http\Response(new JsonSerializableMixedResourcesStub); - - $resource = new JsonSerializableMixedResourcesStub; - - $this->seeJson($resource->jsonSerialize()); - } - - public function testSeeJsonDeeplyNestedPart() - { - $this->response = new Illuminate\Http\Response(new JsonSerializableMixedResourcesStub); - - $this->seeJson(['bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']]); - } - - public function testSeeJsonStructure() - { - $this->response = new Illuminate\Http\Response(new JsonSerializableMixedResourcesStub); - - // At root - $this->seeJsonStructure(['foo']); - - // Nested - $this->seeJsonStructure(['foobar' => ['foobar_foo', 'foobar_bar']]); - - // Wildcard (repeating structure) - $this->seeJsonStructure(['bars' => ['*' => ['bar', 'foo']]]); - - // Nested after wildcard - $this->seeJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo', 'bar']]]]); - - // Wildcard (repeating structure) at root - $this->response = new Illuminate\Http\Response(new JsonSerializableSingleResourceStub); - $this->seeJsonStructure(['*' => ['foo', 'bar', 'foobar']]); - } - - public function testSeeJsonWithNonJson() - { - $this->response = new Illuminate\Http\Response(new NonJsonSerializableStub); - - try { - $this->seeJson(['foo' => 'bad']); - } catch (PHPUnit_Framework_AssertionFailedError $e) { - $this->assertStringStartsWith('Invalid JSON', $e->getMessage()); - - return; - } - - $this->fail('invalid JSON should fail seeJson'); - } - - public function testSeeJsonEqualsWithNonJson() - { - $this->response = new Illuminate\Http\Response(new NonJsonSerializableStub); - - try { - $this->seeJsonEquals(['foo' => 'bad']); - } catch (PHPUnit_Framework_AssertionFailedError $e) { - $this->assertStringStartsWith('Invalid JSON', $e->getMessage()); - - return; - } - - $this->fail('Invalid JSON should fail seeJsonEquals'); - } -} - -class JsonSerializableMixedResourcesStub implements JsonSerializable -{ - public function jsonSerialize() - { - return [ - 'foo' => 'bar', - 'foobar' => [ - 'foobar_foo' => 'foo', - 'foobar_bar' => 'bar', - ], - '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']], - ], - ]; - } -} - -class JsonSerializableSingleResourceStub implements JsonSerializable -{ - public function jsonSerialize() - { - return [ - ['foo' => 'foo 0', 'bar' => 'bar 0', 'foobar' => 'foobar 0'], - ['foo' => 'foo 1', 'bar' => 'bar 1', 'foobar' => 'foobar 1'], - ['foo' => 'foo 2', 'bar' => 'bar 2', 'foobar' => 'foobar 2'], - ['foo' => 'foo 3', 'bar' => 'bar 3', 'foobar' => 'foobar 3'], - ]; - } -} - -class NonJsonSerializableStub implements JsonSerializable -{ - public function jsonSerialize() - { - } -}