transport = new MockTransport(); $this->message = new Message( from: new Email('sender@example.com'), subject: 'Test Subject', body: 'Test body', to: new EmailList(new Email('recipient@example.com')) ); }); describe('basic functionality', function () { it('sends message successfully by default', function () { $result = $this->transport->send($this->message); expect($result->isSuccess())->toBeTrue(); expect($result->getMessageId())->toStartWith('mock_'); expect($this->transport->getSentMessageCount())->toBe(1); }); it('is available by default', function () { expect($this->transport->isAvailable())->toBeTrue(); }); it('returns correct name', function () { expect($this->transport->getName())->toBe('Mock Transport'); }); }); describe('failure simulation', function () { it('can be configured to fail', function () { $this->transport->setShouldFail(true, 'Custom failure message'); $result = $this->transport->send($this->message); expect($result->isFailure())->toBeTrue(); expect($result->getError())->toBe('Custom failure message'); expect($this->transport->getSentMessageCount())->toBe(0); }); it('uses default failure message when none provided', function () { $this->transport->setShouldFail(true); $result = $this->transport->send($this->message); expect($result->getError())->toBe('Mock transport failure'); }); it('can be reset to success mode', function () { $this->transport->setShouldFail(true); $this->transport->setShouldFail(false); $result = $this->transport->send($this->message); expect($result->isSuccess())->toBeTrue(); }); }); describe('availability simulation', function () { it('can be configured as unavailable', function () { $this->transport->setIsAvailable(false); expect($this->transport->isAvailable())->toBeFalse(); }); it('can be reset to available', function () { $this->transport->setIsAvailable(false); $this->transport->setIsAvailable(true); expect($this->transport->isAvailable())->toBeTrue(); }); }); describe('sent message tracking', function () { it('tracks sent messages', function () { $message1 = $this->message; $message2 = new Message( from: new Email('sender@example.com'), subject: 'Second Message', body: 'Second body', to: new EmailList(new Email('recipient2@example.com')) ); $this->transport->send($message1); $this->transport->send($message2); $sentMessages = $this->transport->getSentMessages(); expect($sentMessages)->toHaveCount(2); expect($sentMessages[0]['message'])->toBe($message1); expect($sentMessages[1]['message'])->toBe($message2); expect($sentMessages[0]['sent_at'])->toBeInstanceOf(DateTimeImmutable::class); expect($sentMessages[1]['sent_at'])->toBeInstanceOf(DateTimeImmutable::class); }); it('gets last sent message', function () { $this->transport->send($this->message); $lastMessage = $this->transport->getLastSentMessage(); expect($lastMessage['message'])->toBe($this->message); expect($lastMessage['message_id'])->toStartWith('mock_'); }); it('returns null for last message when none sent', function () { $lastMessage = $this->transport->getLastSentMessage(); expect($lastMessage)->toBeNull(); }); it('clears sent messages', function () { $this->transport->send($this->message); expect($this->transport->getSentMessageCount())->toBe(1); $this->transport->clearSentMessages(); expect($this->transport->getSentMessageCount())->toBe(0); expect($this->transport->getSentMessages())->toBeEmpty(); }); }); describe('recipient checking', function () { it('checks if message was sent to specific email', function () { $this->transport->send($this->message); expect($this->transport->wasSentTo('recipient@example.com'))->toBeTrue(); expect($this->transport->wasSentTo('other@example.com'))->toBeFalse(); }); it('gets messages sent to specific email', function () { $message1 = new Message( from: new Email('sender@example.com'), subject: 'Message 1', body: 'Body 1', to: new EmailList(new Email('user1@example.com')) ); $message2 = new Message( from: new Email('sender@example.com'), subject: 'Message 2', body: 'Body 2', to: new EmailList(new Email('user2@example.com')) ); $message3 = new Message( from: new Email('sender@example.com'), subject: 'Message 3', body: 'Body 3', to: new EmailList(new Email('user1@example.com')) ); $this->transport->send($message1); $this->transport->send($message2); $this->transport->send($message3); $messagesForUser1 = $this->transport->getSentMessagesTo('user1@example.com'); expect($messagesForUser1)->toHaveCount(2); expect($messagesForUser1[0]['message'])->toBe($message1); expect($messagesForUser1[1]['message'])->toBe($message3); }); it('handles messages with multiple recipients', function () { $multiRecipientMessage = new Message( from: new Email('sender@example.com'), subject: 'Multi-recipient', body: 'Body', to: EmailList::fromArray([ new Email('user1@example.com'), new Email('user2@example.com'), ]) ); $this->transport->send($multiRecipientMessage); expect($this->transport->wasSentTo('user1@example.com'))->toBeTrue(); expect($this->transport->wasSentTo('user2@example.com'))->toBeTrue(); expect($this->transport->wasSentTo('user3@example.com'))->toBeFalse(); }); }); describe('subject-based searching', function () { it('finds message by subject', function () { $message1 = new Message( from: new Email('sender@example.com'), subject: 'Welcome Email', body: 'Welcome!', to: new EmailList(new Email('user@example.com')) ); $message2 = new Message( from: new Email('sender@example.com'), subject: 'Password Reset', body: 'Reset your password', to: new EmailList(new Email('user@example.com')) ); $this->transport->send($message1); $this->transport->send($message2); $welcomeMessage = $this->transport->getSentMessageWithSubject('Welcome Email'); $resetMessage = $this->transport->getSentMessageWithSubject('Password Reset'); $nonExistent = $this->transport->getSentMessageWithSubject('Non-existent'); expect($welcomeMessage['message'])->toBe($message1); expect($resetMessage['message'])->toBe($message2); expect($nonExistent)->toBeNull(); }); }); describe('batch sending', function () { it('sends batch of valid messages', function () { $messages = [ new Message( from: new Email('sender@example.com'), subject: 'Message 1', body: 'Body 1', to: new EmailList(new Email('user1@example.com')) ), new Message( from: new Email('sender@example.com'), subject: 'Message 2', body: 'Body 2', to: new EmailList(new Email('user2@example.com')) ), ]; $results = $this->transport->sendBatch($messages); expect($results)->toHaveCount(2); expect($results[0]->isSuccess())->toBeTrue(); expect($results[1]->isSuccess())->toBeTrue(); expect($this->transport->getSentMessageCount())->toBe(2); }); it('handles invalid messages in batch', function () { $batch = [ new Message( from: new Email('sender@example.com'), subject: 'Valid Message', body: 'Body', to: new EmailList(new Email('user@example.com')) ), 'invalid-message', new Message( from: new Email('sender@example.com'), subject: 'Another Valid Message', body: 'Body', to: new EmailList(new Email('user2@example.com')) ), ]; $results = $this->transport->sendBatch($batch); expect($results)->toHaveCount(3); expect($results[0]->isSuccess())->toBeTrue(); expect($results[1]->isFailure())->toBeTrue(); expect($results[1]->getError())->toBe('Invalid message at index 1'); expect($results[2]->isSuccess())->toBeTrue(); expect($this->transport->getSentMessageCount())->toBe(2); }); }); });