Skip to content

Commit 72cf4d1

Browse files
authored
Inherit symfony pre-built assertions (#198)
1 parent 9b77251 commit 72cf4d1

9 files changed

+679
-19
lines changed

composer.json

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"type": "library",
66
"keywords": [
77
"codeception",
8+
"functional testing",
89
"symfony"
910
],
1011
"authors": [
@@ -37,10 +38,12 @@
3738
"symfony/filesystem": "^5.4 | ^6.4 | ^7.0",
3839
"symfony/form": "^5.4 | ^6.4 | ^7.0",
3940
"symfony/framework-bundle": "^5.4 | ^6.4 | ^7.0",
41+
"symfony/http-client": "^5.4 | ^6.4 | ^7.0",
4042
"symfony/http-foundation": "^5.4 | ^6.4 | ^7.0",
4143
"symfony/http-kernel": "^5.4 | ^6.4 | ^7.0",
4244
"symfony/mailer": "^5.4 | ^6.4 | ^7.0",
4345
"symfony/mime": "^5.4 | ^6.4 | ^7.0",
46+
"symfony/notifier": "5.4 | ^6.4 | ^7.0",
4447
"symfony/options-resolver": "^5.4 | ^6.4 | ^7.0",
4548
"symfony/property-access": "^5.4 | ^6.4 | ^7.0",
4649
"symfony/property-info": "^5.4 | ^6.4 | ^7.0",

src/Codeception/Module/Symfony.php

+6
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
use Codeception\Module\Symfony\BrowserAssertionsTrait;
1414
use Codeception\Module\Symfony\ConsoleAssertionsTrait;
1515
use Codeception\Module\Symfony\DoctrineAssertionsTrait;
16+
use Codeception\Module\Symfony\DomCrawlerAssertionsTrait;
1617
use Codeception\Module\Symfony\EventsAssertionsTrait;
1718
use Codeception\Module\Symfony\FormAssertionsTrait;
19+
use Codeception\Module\Symfony\HttpClientAssertionsTrait;
1820
use Codeception\Module\Symfony\MailerAssertionsTrait;
1921
use Codeception\Module\Symfony\MimeAssertionsTrait;
22+
use Codeception\Module\Symfony\NotificationAssertionsTrait;
2023
use Codeception\Module\Symfony\ParameterAssertionsTrait;
2124
use Codeception\Module\Symfony\RouterAssertionsTrait;
2225
use Codeception\Module\Symfony\SecurityAssertionsTrait;
@@ -135,10 +138,13 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule
135138
use BrowserAssertionsTrait;
136139
use ConsoleAssertionsTrait;
137140
use DoctrineAssertionsTrait;
141+
use DomCrawlerAssertionsTrait;
138142
use EventsAssertionsTrait;
139143
use FormAssertionsTrait;
144+
use HttpClientAssertionsTrait;
140145
use MailerAssertionsTrait;
141146
use MimeAssertionsTrait;
147+
use NotificationAssertionsTrait;
142148
use ParameterAssertionsTrait;
143149
use RouterAssertionsTrait;
144150
use SecurityAssertionsTrait;

src/Codeception/Module/Symfony/BrowserAssertionsTrait.php

+194-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,194 @@
44

55
namespace Codeception\Module\Symfony;
66

7+
use PHPUnit\Framework\Constraint\Constraint;
8+
use PHPUnit\Framework\Constraint\LogicalAnd;
9+
use PHPUnit\Framework\Constraint\LogicalNot;
10+
use Symfony\Component\BrowserKit\Test\Constraint\BrowserCookieValueSame;
11+
use Symfony\Component\BrowserKit\Test\Constraint\BrowserHasCookie;
12+
use Symfony\Component\HttpFoundation\Test\Constraint\RequestAttributeValueSame;
13+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseCookieValueSame;
14+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseFormatSame;
15+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasCookie;
16+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHasHeader;
17+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderLocationSame;
18+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseHeaderSame;
19+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsRedirected;
720
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsSuccessful;
21+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsUnprocessable;
22+
use Symfony\Component\HttpFoundation\Test\Constraint\ResponseStatusCodeSame;
823
use function sprintf;
924

1025
trait BrowserAssertionsTrait
1126
{
27+
/**
28+
* Asserts the given cookie in the test Client is set to the expected value.
29+
*/
30+
public function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', ?string $domain = null, string $message = ''): void
31+
{
32+
$this->assertThatForClient(LogicalAnd::fromConstraints(
33+
new BrowserHasCookie($name, $path, $domain),
34+
new BrowserCookieValueSame($name, $expectedValue, $raw, $path, $domain)
35+
), $message);
36+
}
37+
38+
/**
39+
* Asserts that the test Client does have the given cookie set (meaning, the cookie was set by any response in the test).
40+
*/
41+
public function assertBrowserHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
42+
{
43+
$this->assertThatForClient(new BrowserHasCookie($name, $path, $domain), $message);
44+
}
45+
46+
/**
47+
* Asserts that the test Client does not have the given cookie set (meaning, the cookie was set by any response in the test).
48+
*/
49+
public function assertBrowserNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
50+
{
51+
$this->assertThatForClient(new LogicalNot(new BrowserHasCookie($name, $path, $domain)), $message);
52+
}
53+
54+
/**
55+
* Asserts the given request attribute is set to the expected value.
56+
*/
57+
public function assertRequestAttributeValueSame(string $name, string $expectedValue, string $message = ''): void
58+
{
59+
$this->assertThat($this->getClient()->getRequest(), new RequestAttributeValueSame($name, $expectedValue), $message);
60+
}
61+
62+
/**
63+
* Asserts the given cookie is present and set to the expected value.
64+
*/
65+
public function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', ?string $domain = null, string $message = ''): void
66+
{
67+
$this->assertThatForResponse(LogicalAnd::fromConstraints(
68+
new ResponseHasCookie($name, $path, $domain),
69+
new ResponseCookieValueSame($name, $expectedValue, $path, $domain)
70+
), $message);
71+
}
72+
73+
/**
74+
* Asserts the response format returned by the `Response::getFormat()` method is the same as the expected value.
75+
*/
76+
public function assertResponseFormatSame(?string $expectedFormat, string $message = ''): void
77+
{
78+
$this->assertThatForResponse(new ResponseFormatSame($this->getClient()->getRequest(), $expectedFormat), $message);
79+
}
80+
81+
/**
82+
* Asserts the given cookie is present in the response (optionally checking for a specific cookie path or domain).
83+
*/
84+
public function assertResponseHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
85+
{
86+
$this->assertThatForResponse(new ResponseHasCookie($name, $path, $domain), $message);
87+
}
88+
89+
/**
90+
* Asserts the given header is available on the response, e.g. assertResponseHasHeader('content-type');.
91+
*/
92+
public function assertResponseHasHeader(string $headerName, string $message = ''): void
93+
{
94+
$this->assertThatForResponse(new ResponseHasHeader($headerName), $message);
95+
}
96+
97+
/**
98+
* Asserts the given header does not contain the expected value on the response,
99+
* e.g. assertResponseHeaderNotSame('content-type', 'application/octet-stream');.
100+
*/
101+
public function assertResponseHeaderNotSame(string $headerName, string $expectedValue, string $message = ''): void
102+
{
103+
$this->assertThatForResponse(new LogicalNot(new ResponseHeaderSame($headerName, $expectedValue)), $message);
104+
}
105+
106+
/**
107+
* Asserts the given header does contain the expected value on the response,
108+
* e.g. assertResponseHeaderSame('content-type', 'application/octet-stream');.
109+
*/
110+
public function assertResponseHeaderSame(string $headerName, string $expectedValue, string $message = ''): void
111+
{
112+
$this->assertThatForResponse(new ResponseHeaderSame($headerName, $expectedValue), $message);
113+
}
114+
115+
/**
116+
* Asserts that the response was successful (HTTP status is 2xx).
117+
*/
118+
public function assertResponseIsSuccessful(string $message = '', bool $verbose = true): void
119+
{
120+
$this->assertThatForResponse(new ResponseIsSuccessful($verbose), $message);
121+
}
122+
123+
/**
124+
* Asserts the response is unprocessable (HTTP status is 422)
125+
*/
126+
public function assertResponseIsUnprocessable(string $message = '', bool $verbose = true): void
127+
{
128+
$this->assertThatForResponse(new ResponseIsUnprocessable($verbose), $message);
129+
}
130+
131+
/**
132+
* Asserts the given cookie is not present in the response (optionally checking for a specific cookie path or domain).
133+
*/
134+
public function assertResponseNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void
135+
{
136+
$this->assertThatForResponse(new LogicalNot(new ResponseHasCookie($name, $path, $domain)), $message);
137+
}
138+
139+
/**
140+
* Asserts the given header is not available on the response, e.g. assertResponseNotHasHeader('content-type');.
141+
*/
142+
public function assertResponseNotHasHeader(string $headerName, string $message = ''): void
143+
{
144+
$this->assertThatForResponse(new LogicalNot(new ResponseHasHeader($headerName)), $message);
145+
}
146+
147+
/**
148+
* Asserts the response is a redirect response (optionally, you can check the target location and status code).
149+
* The excepted location can be either an absolute or a relative path.
150+
*/
151+
public function assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true): void
152+
{
153+
$constraint = new ResponseIsRedirected($verbose);
154+
if ($expectedLocation) {
155+
if (class_exists(ResponseHeaderLocationSame::class)) {
156+
$locationConstraint = new ResponseHeaderLocationSame($this->getClient()->getRequest(), $expectedLocation);
157+
} else {
158+
$locationConstraint = new ResponseHeaderSame('Location', $expectedLocation);
159+
}
160+
161+
$constraint = LogicalAnd::fromConstraints($constraint, $locationConstraint);
162+
}
163+
if ($expectedCode) {
164+
$constraint = LogicalAnd::fromConstraints($constraint, new ResponseStatusCodeSame($expectedCode));
165+
}
166+
167+
$this->assertThatForResponse($constraint, $message);
168+
}
169+
170+
/**
171+
* Asserts a specific HTTP status code.
172+
*/
173+
public function assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true): void
174+
{
175+
$this->assertThatForResponse(new ResponseStatusCodeSame($expectedCode, $verbose), $message);
176+
}
177+
178+
/**
179+
* Asserts the request matches the given route and optionally route parameters.
180+
*/
181+
public function assertRouteSame(string $expectedRoute, array $parameters = [], string $message = ''): void
182+
{
183+
$constraint = new RequestAttributeValueSame('_route', $expectedRoute);
184+
$constraints = [];
185+
foreach ($parameters as $key => $value) {
186+
$constraints[] = new RequestAttributeValueSame($key, $value);
187+
}
188+
if ($constraints) {
189+
$constraint = LogicalAnd::fromConstraints($constraint, ...$constraints);
190+
}
191+
192+
$this->assertThat($this->getClient()->getRequest(), $constraint, $message);
193+
}
194+
12195
/**
13196
* Reboot client's kernel.
14197
* Can be used to manually reboot kernel when 'rebootable_client' => false
@@ -50,7 +233,7 @@ public function seePageIsAvailable(?string $url = null): void
50233
$this->seeInCurrentUrl($url);
51234
}
52235

53-
$this->assertThat($this->getClient()->getResponse(), new ResponseIsSuccessful());
236+
$this->assertResponseIsSuccessful();
54237
}
55238

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

105288
$this->submitForm($selector, $params, $button);
106289
}
290+
291+
protected function assertThatForClient(Constraint $constraint, string $message = ''): void
292+
{
293+
$this->assertThat($this->getClient(), $constraint, $message);
294+
}
295+
296+
protected function assertThatForResponse(Constraint $constraint, string $message = ''): void
297+
{
298+
$this->assertThat($this->getClient()->getResponse(), $constraint, $message);
299+
}
107300
}

0 commit comments

Comments
 (0)