<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*/
namespace seekquarry\yioop\tests;
use seekquarry\yioop\library\mail\MailComposeBuilder;
use seekquarry\yioop\library\mail\MimeMessage;
use seekquarry\yioop\library\UnitTest;
/**
* Unit tests for MailComposeBuilder, which fills in the compose form
* when replying to or forwarding a parsed message. Each test parses a
* small message and checks the recipients, subject, body, and
* threading context the builder produces.
*
* @author Chris Pollett
*/
class MailComposeBuilderTest extends UnitTest
{
/**
* A sample message replies and forwards are built from.
* @var object
*/
public $source;
/**
* Parses one sample message for the cases to build from.
*/
public function setUp()
{
$raw = "From: Alice <alice@example.com>\r\n" .
"To: Bob <bob@example.com>, Carol <carol@example.com>\r\n" .
"Cc: Dave <dave@example.com>\r\n" .
"Subject: Project update\r\n" .
"Date: Mon, 1 Jan 2026 00:00:00 +0000\r\n" .
"Message-ID: <orig@example.com>\r\n" .
"\r\n" .
"Hello there.\r\n";
$this->source = MimeMessage::parse($raw);
}
/**
* No tearDown is needed.
*/
public function tearDown()
{
}
/**
* replySubject adds the prefix once and never stacks it.
*/
public function replySubjectTestCase()
{
$this->assertEqual('Re: Hi',
MailComposeBuilder::replySubject('Re: ', 'Hi'),
'the prefix is added when absent');
$this->assertEqual('Re: Hi',
MailComposeBuilder::replySubject('Re: ', 'Re: Hi'),
'an existing prefix is not duplicated');
}
/**
* A plain reply addresses the original sender, prefixes the
* subject, quotes the body, and carries the threading context.
*/
public function replyTestCase()
{
$prefill = MailComposeBuilder::replyPrefill($this->source,
'bob@example.com', 'reply', 'INBOX', 5);
$form = $prefill['FORM_VALUES'];
$this->assertEqual('Alice <alice@example.com>', $form['TO'],
'the reply is addressed to the original sender');
$this->assertEqual('Re: Project update', $form['SUBJECT'],
'the subject gets a Re: prefix');
$this->assertTrue(
strpos($form['BODY'], '> Hello there.') !== false,
'the original body is quoted');
$context = $prefill['CONTEXT'];
$this->assertEqual('<orig@example.com>',
$context['MESSAGE_ID'],
'the original message id is kept for threading');
$this->assertEqual(5, $context['UID'],
'the source uid is carried in the context');
}
/**
* Reply-all keeps the other recipients as Cc but drops the
* replying user's own address.
*/
public function replyAllTestCase()
{
$prefill = MailComposeBuilder::replyPrefill($this->source,
'bob@example.com', 'reply_all', 'INBOX', 5);
$cc = $prefill['FORM_VALUES']['CC'];
$this->assertTrue(strpos($cc, 'carol@example.com') !== false,
'the other To recipient moves to Cc');
$this->assertTrue(strpos($cc, 'dave@example.com') !== false,
'the original Cc recipient is kept');
$this->assertTrue(strpos($cc, 'bob@example.com') === false,
'the replying user is not Cc-ed to themselves');
}
/**
* A forward empties the recipients, prefixes Fwd:, and includes
* the forwarded-message banner.
*/
public function forwardTestCase()
{
$prefill = MailComposeBuilder::replyPrefill($this->source,
'bob@example.com', 'forward', 'INBOX', 5);
$form = $prefill['FORM_VALUES'];
$this->assertEqual('', $form['TO'],
'a forward starts with no recipients');
$this->assertEqual('Fwd: Project update', $form['SUBJECT'],
'the subject gets a Fwd: prefix');
$this->assertTrue(strpos($form['BODY'],
'Begin forwarded message:') !== false,
'the forwarded-message banner is present');
}
}