diff --git a/src/Connection/Responses/MessageResponseParser.php b/src/Connection/Responses/MessageResponseParser.php new file mode 100644 index 0000000..70f25b2 --- /dev/null +++ b/src/Connection/Responses/MessageResponseParser.php @@ -0,0 +1,51 @@ + + */ + public static function getFlags(UntaggedResponse $response): array + { + $data = $response->tokenAt(3); + + $uid = $data->lookup('UID')->value; + $flags = $data->lookup('FLAGS')->values(); + + return [$uid => $flags]; + } + + /** + * Get the body header from an untagged response. + * + * @return array + */ + public static function getBodyHeader(UntaggedResponse $response): array + { + $data = $response->tokenAt(3); + + $uid = $data->lookup('UID')->value; + $headers = $data->lookup('[HEADER]')->value; + + return [$uid => $headers]; + } + + /** + * Get the body text from an untagged response. + * + * @return array + */ + public static function getBodyText(UntaggedResponse $response): array + { + $data = $response->tokenAt(3); + + $uid = $data->lookup('UID')->value; + $contents = $data->lookup('[TEXT]')->value; + + return [$uid => $contents]; + } +} diff --git a/src/MessageQuery.php b/src/MessageQuery.php index 14a90bb..b1fca65 100644 --- a/src/MessageQuery.php +++ b/src/MessageQuery.php @@ -6,6 +6,7 @@ use DirectoryTree\ImapEngine\Collections\ResponseCollection; use DirectoryTree\ImapEngine\Connection\ConnectionInterface; use DirectoryTree\ImapEngine\Connection\ImapQueryBuilder; +use DirectoryTree\ImapEngine\Connection\Responses\MessageResponseParser; use DirectoryTree\ImapEngine\Connection\Responses\UntaggedResponse; use DirectoryTree\ImapEngine\Connection\Tokens\Atom; use DirectoryTree\ImapEngine\Enums\ImapFetchIdentifier; @@ -336,36 +337,15 @@ protected function fetch(Collection $messages): array $flags = $this->fetchFlags ? $this->connection() ->flags($uids) - ->mapWithKeys(function (UntaggedResponse $response) { - $data = $response->tokenAt(3); - - $uid = $data->lookup('UID')->value; - $flags = $data->lookup('FLAGS')->values(); - - return [$uid => $flags]; - }) : new Collection; + ->mapWithKeys(MessageResponseParser::getFlags(...))->all() : []; $headers = $this->fetchHeaders ? $this->connection() ->bodyHeader($uids, $this->fetchAsUnread) - ->mapWithKeys(function (UntaggedResponse $response) { - $data = $response->tokenAt(3); - - $uid = $data->lookup('UID')->value; - $headers = $data->lookup('[HEADER]')->value; - - return [$uid => $headers]; - }) : new Collection; + ->mapWithKeys(MessageResponseParser::getBodyHeader(...))->all() : []; $contents = $this->fetchBody ? $this->connection() ->bodyText($uids, $this->fetchAsUnread) - ->mapWithKeys(function (UntaggedResponse $response) { - $data = $response->tokenAt(3); - - $uid = $data->lookup('UID')->value; - $contents = $data->lookup('[TEXT]')->value; - - return [$uid => $contents]; - }) : new Collection; + ->mapWithKeys(MessageResponseParser::getBodyText(...))->all() : []; return [ 'uids' => $uids, @@ -380,13 +360,7 @@ protected function fetch(Collection $messages): array */ protected function newMessage(int $uid, array $flags, string $headers, string $contents): Message { - return new Message( - $this->folder, - $uid, - $flags, - $headers, - $contents, - ); + return new Message($this->folder, $uid, $flags, $headers, $contents); } /** @@ -446,11 +420,11 @@ public function get(): MessageCollection */ public function append(string $message, mixed $flags = null): int { - $result = $this->connection()->append( + $response = $this->connection()->append( $this->folder->path(), $message, Str::enums($flags), ); - return $result // TAG4 OK [APPENDUID ] APPEND completed. + return $response // TAG4 OK [APPENDUID ] APPEND completed. ->tokenAt(2) // [APPENDUID ] ->tokenAt(2) // ->value; diff --git a/tests/Unit/Connection/Responses/MessageResponseParser.php b/tests/Unit/Connection/Responses/MessageResponseParser.php new file mode 100644 index 0000000..db0d0f4 --- /dev/null +++ b/tests/Unit/Connection/Responses/MessageResponseParser.php @@ -0,0 +1,91 @@ +toBe([ + '12345' => ['\Seen', '\Answered', '$Important'], + ]); +}); + +it('parses body header from untagged response', function () { + $headerContent = "From: sender@example.com\r\nTo: recipient@example.com\r\nSubject: Test Email Header\r\n"; + + $response = new UntaggedResponse([ + new Atom('*'), // Untagged marker + new Atom('2'), // Sequence number (example) + new Atom('FETCH'), // Command type + new ListData([ // Data list + new Atom('UID'), + new Atom('54321'), // The message UID + new Atom('BODY'), + new Atom('[HEADER]'), // Specifies header part + new Literal($headerContent), // The header content as a literal + ]), + ]); + + $parsedHeader = MessageResponseParser::getBodyHeader($response); // + + expect($parsedHeader)->toBe(['54321' => $headerContent]); +}); + +it('parses body text from untagged response', function () { + $textContent = "This is the plain text body of the email.\r\nIt might have multiple lines.\r\n"; + + $response = new UntaggedResponse([ + new Atom('*'), // Untagged marker + new Atom('3'), // Sequence number (example) + new Atom('FETCH'), // Command type + new ListData([ // Data list + new Atom('UID'), + new Atom('98765'), // The message UID + new Atom('BODY'), + new Atom('[TEXT]'), // Specifies text part + new Literal($textContent), // The text content as a literal + ]), + ]); + + $parsedText = MessageResponseParser::getBodyText($response); + + expect($parsedText)->toBe(['98765' => $textContent]); +}); + +it('handles empty flags list correctly', function () { + $response = new UntaggedResponse([ + new Atom('*'), + new Atom('4'), + new Atom('FETCH'), + new ListData([ + new Atom('UID'), + new Atom('11111'), + new Atom('FLAGS'), + new ListData([]), // Empty flags list + ]), + ]); + + $parsedFlags = MessageResponseParser::getFlags($response); + + expect($parsedFlags)->toBe(['11111' => []]); +});