Skip to content

Commit ee68e5a

Browse files
authored
Merge pull request #120 from Codeception/mailer-proxy-alternative
feat: allow mails to be intercepted using events
2 parents ce1e2fa + 602a67c commit ee68e5a

File tree

4 files changed

+93
-116
lines changed

4 files changed

+93
-116
lines changed

phpstan-baseline.neon

-60
Original file line numberDiff line numberDiff line change
@@ -1092,12 +1092,6 @@ parameters:
10921092
count: 1
10931093
path: tests/_support/FunctionalTester.php
10941094

1095-
-
1096-
message: '#^Method tests\\FunctionalTester\:\:createAndSetCsrfCookie\(\) should return array\<string\> but returns mixed\.$#'
1097-
identifier: return.type
1098-
count: 1
1099-
path: tests/_support/FunctionalTester.php
1100-
11011095
-
11021096
message: '#^Method tests\\FunctionalTester\:\:dontSee\(\) has parameter \$selector with no value type specified in iterable type array\.$#'
11031097
identifier: missingType.iterableValue
@@ -1194,12 +1188,6 @@ parameters:
11941188
count: 1
11951189
path: tests/_support/FunctionalTester.php
11961190

1197-
-
1198-
message: '#^Method tests\\FunctionalTester\:\:getInternalDomains\(\) should return non\-empty\-list\<string\> but returns mixed\.$#'
1199-
identifier: return.type
1200-
count: 1
1201-
path: tests/_support/FunctionalTester.php
1202-
12031191
-
12041192
message: '#^Method tests\\FunctionalTester\:\:grabAttributeFrom\(\) has parameter \$cssOrXpath with no type specified\.$#'
12051193
identifier: missingType.parameter
@@ -1212,48 +1200,18 @@ parameters:
12121200
count: 1
12131201
path: tests/_support/FunctionalTester.php
12141202

1215-
-
1216-
message: '#^Method tests\\FunctionalTester\:\:grabFixture\(\) should return yii\\db\\ActiveRecord\|yii\\test\\Fixture\|null but returns mixed\.$#'
1217-
identifier: return.type
1218-
count: 1
1219-
path: tests/_support/FunctionalTester.php
1220-
12211203
-
12221204
message: '#^Method tests\\FunctionalTester\:\:grabFixtures\(\) has invalid return type tests\\_generated\\Fixture\.$#'
12231205
identifier: class.notFound
12241206
count: 1
12251207
path: tests/_support/FunctionalTester.php
12261208

1227-
-
1228-
message: '#^Method tests\\FunctionalTester\:\:grabFixtures\(\) should return array\<string, tests\\_generated\\Fixture\> but returns mixed\.$#'
1229-
identifier: return.type
1230-
count: 1
1231-
path: tests/_support/FunctionalTester.php
1232-
1233-
-
1234-
message: '#^Method tests\\FunctionalTester\:\:grabLastSentEmail\(\) should return yii\\mail\\BaseMessage\|null but returns mixed\.$#'
1235-
identifier: return.type
1236-
count: 1
1237-
path: tests/_support/FunctionalTester.php
1238-
12391209
-
12401210
message: '#^Method tests\\FunctionalTester\:\:grabMultiple\(\) has parameter \$cssOrXpath with no type specified\.$#'
12411211
identifier: missingType.parameter
12421212
count: 1
12431213
path: tests/_support/FunctionalTester.php
12441214

1245-
-
1246-
message: '#^Method tests\\FunctionalTester\:\:grabMultiple\(\) should return array\<string\> but returns mixed\.$#'
1247-
identifier: return.type
1248-
count: 1
1249-
path: tests/_support/FunctionalTester.php
1250-
1251-
-
1252-
message: '#^Method tests\\FunctionalTester\:\:grabPageSource\(\) should return string but returns mixed\.$#'
1253-
identifier: return.type
1254-
count: 1
1255-
path: tests/_support/FunctionalTester.php
1256-
12571215
-
12581216
message: '#^Method tests\\FunctionalTester\:\:grabRecord\(\) has invalid return type tests\\_generated\\ActiveRecordInterface\.$#'
12591217
identifier: class.notFound
@@ -1266,30 +1224,12 @@ parameters:
12661224
count: 1
12671225
path: tests/_support/FunctionalTester.php
12681226

1269-
-
1270-
message: '#^Method tests\\FunctionalTester\:\:grabRecord\(\) should return array\|yii\\db\\ActiveRecordInterface\|null but returns mixed\.$#'
1271-
identifier: return.type
1272-
count: 1
1273-
path: tests/_support/FunctionalTester.php
1274-
1275-
-
1276-
message: '#^Method tests\\FunctionalTester\:\:grabSentEmails\(\) has invalid return type tests\\_generated\\BaseMessage\.$#'
1277-
identifier: class.notFound
1278-
count: 1
1279-
path: tests/_support/FunctionalTester.php
1280-
12811227
-
12821228
message: '#^Method tests\\FunctionalTester\:\:grabSentEmails\(\) has invalid return type tests\\_generated\\MessageInterface\.$#'
12831229
identifier: class.notFound
12841230
count: 1
12851231
path: tests/_support/FunctionalTester.php
12861232

1287-
-
1288-
message: '#^Method tests\\FunctionalTester\:\:grabSentEmails\(\) should return list\<tests\\_generated\\BaseMessage&tests\\_generated\\MessageInterface\> but returns mixed\.$#'
1289-
identifier: return.type
1290-
count: 1
1291-
path: tests/_support/FunctionalTester.php
1292-
12931233
-
12941234
message: '#^Method tests\\FunctionalTester\:\:grabTextFrom\(\) has parameter \$cssOrXPathOrRegex with no type specified\.$#'
12951235
identifier: missingType.parameter

src/Codeception/Lib/Connector/Yii2.php

+47-15
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
use yii\base\ExitException;
2222
use yii\base\Security;
2323
use yii\base\UserException;
24-
use yii\mail\BaseMessage;
24+
use yii\mail\BaseMailer;
25+
use yii\mail\MailEvent;
26+
use yii\mail\MessageInterface;
2527
use yii\web\Application;
2628
use yii\web\IdentityInterface;
2729
use yii\web\Request as YiiRequest;
@@ -36,7 +38,22 @@ final class Yii2 extends Client
3638
{
3739
use Shared\PhpSuperGlobalsConverter;
3840

39-
public const CLEAN_METHODS = [
41+
public const array MAIL_METHODS = [
42+
self::MAIL_CATCH,
43+
self::MAIL_EVENT_AFTER,
44+
self::MAIL_EVENT_BEFORE,
45+
self::MAIL_IGNORE
46+
];
47+
48+
public const string MAIL_CATCH = 'catch';
49+
50+
public const string MAIL_EVENT_AFTER = 'after';
51+
52+
public const string MAIL_EVENT_BEFORE = 'before';
53+
54+
public const string MAIL_IGNORE = 'ignore';
55+
56+
public const array CLEAN_METHODS = [
4057
self::CLEAN_RECREATE,
4158
self::CLEAN_CLEAR,
4259
self::CLEAN_FORCE_RECREATE,
@@ -47,54 +64,59 @@ final class Yii2 extends Client
4764
* Clean the response object by recreating it.
4865
* This might lose behaviors / event handlers / other changes that are done in the application bootstrap phase.
4966
*/
50-
public const CLEAN_RECREATE = 'recreate';
67+
public const string CLEAN_RECREATE = 'recreate';
5168

5269
/**
5370
* Same as recreate but will not warn when behaviors / event handlers are lost.
5471
*/
55-
public const CLEAN_FORCE_RECREATE = 'force_recreate';
72+
public const string CLEAN_FORCE_RECREATE = 'force_recreate';
5673

5774
/**
5875
* Clean the response object by resetting specific properties via its' `clear()` method.
5976
* This will keep behaviors / event handlers, but could inadvertently leave some changes intact.
6077
*
6178
* @see \yii\web\Response::clear()
6279
*/
63-
public const CLEAN_CLEAR = 'clear';
80+
public const string CLEAN_CLEAR = 'clear';
6481

6582
/**
6683
* Do not clean the response, instead the test writer will be responsible for manually resetting the response in
6784
* between requests during one test
6885
*/
69-
public const CLEAN_MANUAL = 'manual';
86+
public const string CLEAN_MANUAL = 'manual';
7087

7188
/**
7289
* @var string application config file
7390
*/
74-
public $configFile;
91+
public string $configFile;
92+
93+
/**
94+
* @var self::MAIL_CATCH|self::MAIL_IGNORE|self::MAIL_EVENT_AFTER|self::MAIL_EVENT_BEFORE method for handling mails
95+
*/
96+
public string $mailMethod;
7597

7698
/**
7799
* @var string method for cleaning the response object before each request
78100
*/
79-
public $responseCleanMethod;
101+
public string $responseCleanMethod;
80102

81103
/**
82104
* @var string method for cleaning the request object before each request
83105
*/
84-
public $requestCleanMethod;
106+
public string $requestCleanMethod;
85107

86108
/**
87109
* @var string[] List of component names that must be recreated before each request
88110
*/
89-
public $recreateComponents = [];
111+
public array $recreateComponents = [];
90112

91113
/**
92114
* This option is there primarily for backwards compatibility.
93115
* It means you cannot make any modification to application state inside your app, since they will get discarded.
94116
*
95117
* @var bool whether to recreate the whole application before each request
96118
*/
97-
public $recreateApplication = false;
119+
public bool $recreateApplication = false;
98120

99121
/**
100122
* @var bool whether to close the session in between requests inside a single test, if recreateApplication is set to true
@@ -108,7 +130,7 @@ final class Yii2 extends Client
108130
public string|null $applicationClass = null;
109131

110132
/**
111-
* @var list<BaseMessage>
133+
* @var list<MessageInterface>
112134
*/
113135
private array $emails = [];
114136

@@ -213,7 +235,7 @@ public function getInternalDomains(): array
213235

214236
/**
215237
* @internal
216-
* @return list<BaseMessage> List of sent emails
238+
* @return list<MessageInterface> List of sent emails
217239
*/
218240
public function getEmails(): array
219241
{
@@ -281,7 +303,17 @@ public function startApp(?\yii\log\Logger $logger = null): void
281303
unset($config['container']);
282304
}
283305

284-
$config = $this->mockMailer($config);
306+
match ($this->mailMethod) {
307+
self::MAIL_CATCH => $config = $this->mockMailer($config),
308+
self::MAIL_EVENT_AFTER => $config['components']['mailer']['on ' . BaseMailer::EVENT_AFTER_SEND] = function (MailEvent $event): void {
309+
if ($event->isSuccessful) {
310+
$this->emails[] = $event->message;
311+
}
312+
},
313+
self::MAIL_EVENT_BEFORE => $config['components']['mailer']['on ' . BaseMailer::EVENT_BEFORE_SEND] = fn (MailEvent $event) => $this->emails[] = $event->message,
314+
self::MAIL_IGNORE => null// Do nothing
315+
};
316+
285317
$app = Yii::createObject($config);
286318
if (! $app instanceof \yii\base\Application) {
287319
throw new ModuleConfigException($this, "Failed to initialize Yii2 app");
@@ -450,7 +482,7 @@ protected function mockMailer(array $config): array
450482

451483
$mailerConfig = [
452484
'class' => TestMailer::class,
453-
'callback' => function (BaseMessage $message): void {
485+
'callback' => function (MessageInterface $message): void {
454486
$this->emails[] = $message;
455487
},
456488
];

src/Codeception/Lib/Connector/Yii2/TestMailer.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66

77
use Closure;
88
use yii\mail\BaseMailer;
9+
use yii\symfonymailer\Message;
910

1011
final class TestMailer extends BaseMailer
1112
{
12-
public $messageClass = \yii\symfonymailer\Message::class;
13+
public $messageClass = Message::class;
1314

1415
public Closure $callback;
1516

0 commit comments

Comments
 (0)