Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit Symfony pre-built assertions #198

Merged
merged 1 commit into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"type": "library",
"keywords": [
"codeception",
"functional testing",
"symfony"
],
"authors": [
Expand Down Expand Up @@ -37,10 +38,12 @@
"symfony/filesystem": "^5.4 | ^6.4 | ^7.0",
"symfony/form": "^5.4 | ^6.4 | ^7.0",
"symfony/framework-bundle": "^5.4 | ^6.4 | ^7.0",
"symfony/http-client": "^5.4 | ^6.4 | ^7.0",
"symfony/http-foundation": "^5.4 | ^6.4 | ^7.0",
"symfony/http-kernel": "^5.4 | ^6.4 | ^7.0",
"symfony/mailer": "^5.4 | ^6.4 | ^7.0",
"symfony/mime": "^5.4 | ^6.4 | ^7.0",
"symfony/notifier": "5.4 | ^6.4 | ^7.0",
"symfony/options-resolver": "^5.4 | ^6.4 | ^7.0",
"symfony/property-access": "^5.4 | ^6.4 | ^7.0",
"symfony/property-info": "^5.4 | ^6.4 | ^7.0",
Expand Down
6 changes: 6 additions & 0 deletions src/Codeception/Module/Symfony.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
use Codeception\Module\Symfony\BrowserAssertionsTrait;
use Codeception\Module\Symfony\ConsoleAssertionsTrait;
use Codeception\Module\Symfony\DoctrineAssertionsTrait;
use Codeception\Module\Symfony\DomCrawlerAssertionsTrait;
use Codeception\Module\Symfony\EventsAssertionsTrait;
use Codeception\Module\Symfony\FormAssertionsTrait;
use Codeception\Module\Symfony\HttpClientAssertionsTrait;
use Codeception\Module\Symfony\MailerAssertionsTrait;
use Codeception\Module\Symfony\MimeAssertionsTrait;
use Codeception\Module\Symfony\NotificationAssertionsTrait;
use Codeception\Module\Symfony\ParameterAssertionsTrait;
use Codeception\Module\Symfony\RouterAssertionsTrait;
use Codeception\Module\Symfony\SecurityAssertionsTrait;
Expand Down Expand Up @@ -135,10 +138,13 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule
use BrowserAssertionsTrait;
use ConsoleAssertionsTrait;
use DoctrineAssertionsTrait;
use DomCrawlerAssertionsTrait;
use EventsAssertionsTrait;
use FormAssertionsTrait;
use HttpClientAssertionsTrait;
use MailerAssertionsTrait;
use MimeAssertionsTrait;
use NotificationAssertionsTrait;
use ParameterAssertionsTrait;
use RouterAssertionsTrait;
use SecurityAssertionsTrait;
Expand Down
195 changes: 194 additions & 1 deletion src/Codeception/Module/Symfony/BrowserAssertionsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,194 @@

namespace Codeception\Module\Symfony;

use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\Constraint\LogicalAnd;
use PHPUnit\Framework\Constraint\LogicalNot;
use Symfony\Component\BrowserKit\Test\Constraint\BrowserCookieValueSame;
use Symfony\Component\BrowserKit\Test\Constraint\BrowserHasCookie;
use Symfony\Component\HttpFoundation\Test\Constraint\RequestAttributeValueSame;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseCookieValueSame;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseFormatSame;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasCookie;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasHeader;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderLocationSame;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderSame;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsRedirected;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsSuccessful;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsUnprocessable;
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseStatusCodeSame;
use function sprintf;

trait BrowserAssertionsTrait
{
/**
* Asserts the given cookie in the test Client is set to the expected value.
*/
public function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForClient(LogicalAnd::fromConstraints(
new BrowserHasCookie($name, $path, $domain),
new BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain)
), $message);
}

/**
* Asserts that the test Client does have the given cookie set (meaning, the cookie was set by any response in the test).
*/
public function assertBrowserHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForClient(new BrowserHasCookie($name, $path, $domain), $message);
}

/**
* Asserts that the test Client does not have the given cookie set (meaning, the cookie was set by any response in the test).
*/
public function assertBrowserNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForClient(new LogicalNot(new BrowserHasCookie($name, $path, $domain)), $message);
}

/**
* Asserts the given request attribute is set to the expected value.
*/
public function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void
{
$this->assertThat($this->getClient()->getRequest(), new RequestAttributeValueSame($name, $expectedValue), $message);
}

/**
* Asserts the given cookie is present and set to the expected value.
*/
public function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForResponse(LogicalAnd::fromConstraints(
new ResponseHasCookie($name, $path, $domain),
new ResponseCookieValueSame($name, $expectedValue, $path, $domain)
), $message);
}

/**
* Asserts the response format returned by the `Response::getFormat()` method is the same as the expected value.
*/
public function assertResponseFormatSame(?string $expectedFormat, string $message = ''): void
{
$this->assertThatForResponse(new ResponseFormatSame($this->getClient()->getRequest(), $expectedFormat), $message);
}

/**
* Asserts the given cookie is present in the response (optionally checking for a specific cookie path or domain).
*/
public function assertResponseHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForResponse(new ResponseHasCookie($name, $path, $domain), $message);
}

/**
* Asserts the given header is available on the response, e.g. assertResponseHasHeader('content-type');.
*/
public function assertResponseHasHeader(string $headerName, string $message = ''): void
{
$this->assertThatForResponse(new ResponseHasHeader($headerName), $message);
}

/**
* Asserts the given header does not contain the expected value on the response,
* e.g. assertResponseHeaderNotSame('content-type', 'application/octet-stream');.
*/
public function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void
{
$this->assertThatForResponse(new LogicalNot(new ResponseHeaderSame($headerName, $expectedValue)), $message);
}

/**
* Asserts the given header does contain the expected value on the response,
* e.g. assertResponseHeaderSame('content-type', 'application/octet-stream');.
*/
public function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void
{
$this->assertThatForResponse(new ResponseHeaderSame($headerName, $expectedValue), $message);
}

/**
* Asserts that the response was successful (HTTP status is 2xx).
*/
public function assertResponseIsSuccessful(string $message = '', bool $verbose = true): void
{
$this->assertThatForResponse(new ResponseIsSuccessful($verbose), $message);
}

/**
* Asserts the response is unprocessable (HTTP status is 422)
*/
public function assertResponseIsUnprocessable(string $message = '', bool $verbose = true): void
{
$this->assertThatForResponse(new ResponseIsUnprocessable($verbose), $message);
}

/**
* Asserts the given cookie is not present in the response (optionally checking for a specific cookie path or domain).
*/
public function assertResponseNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
{
$this->assertThatForResponse(new LogicalNot(new ResponseHasCookie($name, $path, $domain)), $message);
}

/**
* Asserts the given header is not available on the response, e.g. assertResponseNotHasHeader('content-type');.
*/
public function assertResponseNotHasHeader(string $headerName, string $message = ''): void
{
$this->assertThatForResponse(new LogicalNot(new ResponseHasHeader($headerName)), $message);
}

/**
* Asserts the response is a redirect response (optionally, you can check the target location and status code).
* The excepted location can be either an absolute or a relative path.
*/
public function assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true): void
{
$constraint = new ResponseIsRedirected($verbose);
if ($expectedLocation) {
if (class_exists(ResponseHeaderLocationSame::class)) {
$locationConstraint = new ResponseHeaderLocationSame($this->getClient()->getRequest(), $expectedLocation);
} else {
$locationConstraint = new ResponseHeaderSame('Location', $expectedLocation);
}

$constraint = LogicalAnd::fromConstraints($constraint, $locationConstraint);
}
if ($expectedCode) {
$constraint = LogicalAnd::fromConstraints($constraint, new ResponseStatusCodeSame($expectedCode));
}

$this->assertThatForResponse($constraint, $message);
}

/**
* Asserts a specific HTTP status code.
*/
public function assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true): void
{
$this->assertThatForResponse(new ResponseStatusCodeSame($expectedCode, $verbose), $message);
}

/**
* Asserts the request matches the given route and optionally route parameters.
*/
public function assertRouteSame(string $expectedRoute, array $parameters = [], string $message = ''): void
{
$constraint = new RequestAttributeValueSame('_route', $expectedRoute);
$constraints = [];
foreach ($parameters as $key => $value) {
$constraints[] = new RequestAttributeValueSame($key, $value);
}
if ($constraints) {
$constraint = LogicalAnd::fromConstraints($constraint, ...$constraints);
}

$this->assertThat($this->getClient()->getRequest(), $constraint, $message);
}

/**
* Reboot client's kernel.
* Can be used to manually reboot kernel when 'rebootable_client' => false
Expand Down Expand Up @@ -50,7 +233,7 @@ public function seePageIsAvailable(?string $url = null): void
$this->seeInCurrentUrl($url);
}

$this->assertThat($this->getClient()->getResponse(), new ResponseIsSuccessful());
$this->assertResponseIsSuccessful();
}

/**
Expand Down Expand Up @@ -104,4 +287,14 @@ public function submitSymfonyForm(string $name, array $fields): void

$this->submitForm($selector, $params, $button);
}

protected function assertThatForClient(Constraint $constraint, string $message = ''): void
{
$this->assertThat($this->getClient(), $constraint, $message);
}

protected function assertThatForResponse(Constraint $constraint, string $message = ''): void
{
$this->assertThat($this->getClient()->getResponse(), $constraint, $message);
}
}
Loading
Loading