Skip to content

Commit 486e4a9

Browse files
authored
Merge pull request #5 from DirectoryTree/mailbox-watch-method
Add `method` option to `imap:watch` command
2 parents 50a845c + d670dc1 commit 486e4a9

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"require": {
1919
"php": "^8.1",
20-
"directorytree/imapengine": "^1.13.0",
20+
"directorytree/imapengine": "^1.19.0",
2121
"illuminate/contracts": "^10.0|^11.0|^12.0"
2222
},
2323
"require-dev": {

src/Commands/WatchMailbox.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
use DirectoryTree\ImapEngine\Laravel\Facades\Imap;
88
use DirectoryTree\ImapEngine\Laravel\Support\LoopInterface;
99
use DirectoryTree\ImapEngine\MailboxInterface;
10-
use DirectoryTree\ImapEngine\Message;
1110
use Exception;
1211
use Illuminate\Console\Command;
1312
use Illuminate\Support\Facades\Event;
1413
use Illuminate\Support\Str;
14+
use Symfony\Component\Console\Exception\InvalidOptionException;
1515

1616
class WatchMailbox extends Command
1717
{
@@ -20,7 +20,7 @@ class WatchMailbox extends Command
2020
*
2121
* @var string
2222
*/
23-
protected $signature = 'imap:watch {mailbox} {folder?} {--with=} {--timeout=30} {--attempts=5} {--debug=false}';
23+
protected $signature = 'imap:watch {mailbox} {folder?} {--method=idle} {--with=} {--timeout=30} {--attempts=5} {--debug=false}';
2424

2525
/**
2626
* The console command description.
@@ -34,6 +34,10 @@ class WatchMailbox extends Command
3434
*/
3535
public function handle(LoopInterface $loop): void
3636
{
37+
if (! in_array($method = $this->option('method'), ['idle', 'poll'])) {
38+
throw new InvalidOptionException("Invalid method [{$method}]. Valid options are [idle, poll].");
39+
}
40+
3741
$mailbox = Imap::mailbox($name = $this->argument('mailbox'));
3842

3943
$with = explode(',', $this->option('with'));
@@ -48,11 +52,18 @@ public function handle(LoopInterface $loop): void
4852
try {
4953
$folder = $this->folder($mailbox);
5054

51-
$folder->idle(
52-
new HandleMessageReceived($this, $attempts, $lastReceivedAt),
53-
new ConfigureIdleQuery($with),
54-
$this->option('timeout')
55-
);
55+
match ($this->option('method')) {
56+
'idle' => $folder->idle(
57+
new HandleMessageReceived($this, $attempts, $lastReceivedAt),
58+
new ConfigureIdleQuery($with),
59+
$this->option('timeout'),
60+
),
61+
'poll' => $folder->poll(
62+
new HandleMessageReceived($this, $attempts, $lastReceivedAt),
63+
new ConfigureIdleQuery($with),
64+
$this->option('timeout'),
65+
),
66+
};
5667
} catch (Exception $e) {
5768
if ($this->isMessageMissing($e)) {
5869
return;

tests/Commands/WatchMailboxTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Illuminate\Support\Facades\Event;
1616
use InvalidArgumentException;
1717
use RuntimeException;
18+
use Symfony\Component\Console\Exception\InvalidOptionException;
1819

1920
use function Pest\Laravel\artisan;
2021

@@ -51,6 +52,35 @@
5152
);
5253
});
5354

55+
it('can watch mailbox using method', function (string $method) {
56+
Config::set('imap.mailboxes.test', [
57+
'host' => 'localhost',
58+
'port' => 993,
59+
'encryption' => 'ssl',
60+
'username' => '',
61+
'password' => '',
62+
]);
63+
64+
Imap::fake('test', folders: [
65+
new FakeFolder('inbox', messages: [
66+
$message = new FakeMessage(uid: 1),
67+
]),
68+
]);
69+
70+
App::bind(LoopInterface::class, LoopFake::class);
71+
72+
Event::fake();
73+
74+
artisan(WatchMailbox::class, [
75+
'mailbox' => 'test',
76+
'--method' => $method,
77+
])->assertSuccessful();
78+
79+
Event::assertDispatched(
80+
fn (MessageReceived $event) => $event->message->is($message)
81+
);
82+
})->with(['idle', 'poll']);
83+
5484
it('dispatches event when failure attempts have been reached', function () {
5585
Config::set('imap.mailboxes.test', [
5686
'host' => 'localhost',
@@ -91,3 +121,27 @@ public function idle(
91121
&& $event->exception->getMessage() === 'Simulated exception';
92122
});
93123
});
124+
125+
it('throws exception when invalid method is provided', function () {
126+
Config::set('imap.mailboxes.test', [
127+
'host' => 'localhost',
128+
'port' => 993,
129+
'encryption' => 'ssl',
130+
'username' => '',
131+
'password' => '',
132+
]);
133+
134+
Imap::fake('test', folders: [
135+
new FakeFolder('inbox'),
136+
]);
137+
138+
App::bind(LoopInterface::class, LoopFake::class);
139+
140+
artisan(WatchMailbox::class, [
141+
'mailbox' => 'test',
142+
'--method' => 'invalid',
143+
]);
144+
})->throws(
145+
InvalidOptionException::class,
146+
'Invalid method [invalid]. Valid options are [idle, poll].'
147+
);

0 commit comments

Comments
 (0)