Skip to content

Commit 3b9b377

Browse files
committed
Add ability to create connections with a fake stream and fix issue with unsolicited fetch responses
1 parent fa9bb3b commit 3b9b377

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/Connection/ImapConnection.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
use DirectoryTree\ImapEngine\Connection\Loggers\LoggerInterface;
77
use DirectoryTree\ImapEngine\Connection\Responses\ContinuationResponse;
88
use DirectoryTree\ImapEngine\Connection\Responses\Data\Data;
9+
use DirectoryTree\ImapEngine\Connection\Responses\Data\ListData;
910
use DirectoryTree\ImapEngine\Connection\Responses\Response;
1011
use DirectoryTree\ImapEngine\Connection\Responses\TaggedResponse;
1112
use DirectoryTree\ImapEngine\Connection\Responses\UntaggedResponse;
13+
use DirectoryTree\ImapEngine\Connection\Streams\FakeStream;
1214
use DirectoryTree\ImapEngine\Connection\Streams\StreamInterface;
1315
use DirectoryTree\ImapEngine\Connection\Tokens\Token;
1416
use DirectoryTree\ImapEngine\Enums\ImapFetchIdentifier;
@@ -49,6 +51,20 @@ public function __construct(
4951
protected ?LoggerInterface $logger = null,
5052
) {}
5153

54+
/**
55+
* Create a new connection with a fake stream.
56+
*/
57+
public static function fake(array $responses = []): static
58+
{
59+
$stream = new FakeStream;
60+
61+
$stream->open();
62+
63+
$stream->feed($responses);
64+
65+
return new static($stream);
66+
}
67+
5268
/**
5369
* Tear down the connection.
5470
*/
@@ -602,13 +618,18 @@ public function fetch(array|string $items, array|int $from, mixed $to = null, Im
602618
// << * 123 FETCH (UID 456 BODY[TEXT] {14}\nHello, World!)
603619
// << * 123 FETCH (FLAGS (\Seen)) <-- Unsolicited response
604620
return $this->result->responses()->untagged()->filter(function (UntaggedResponse $response) use ($items, $identifier) {
605-
// The third token will always be a list of data items.
621+
// Skip over any untagged responses that are not FETCH responses.
622+
// The third token should always be the list of data items.
623+
if (! ($data = $response->tokenAt(3)) instanceof ListData) {
624+
return false;
625+
}
626+
606627
return match ($identifier) {
607628
// If we're fetching UIDs, we can check if a UID token is contained in the list.
608-
ImapFetchIdentifier::Uid => $response->tokenAt(3)->contains('UID'),
629+
ImapFetchIdentifier::Uid => $data->contains('UID'),
609630

610631
// If we're fetching message numbers, we can check if the requested items are all contained in the list.
611-
ImapFetchIdentifier::MessageNumber => $response->tokenAt(3)->contains($items),
632+
ImapFetchIdentifier::MessageNumber => $data->contains($items),
612633
};
613634
});
614635
}

0 commit comments

Comments
 (0)