/ tests / OutboundMailClientTest.php
<?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\configs as C;
use seekquarry\yioop\library\mail\MailSiteFactory;
use seekquarry\yioop\library\UnitTest;

/**
 * Tests how the client that sends the site's own outgoing mail is
 * built. When the bot/MailSite route is on, the connection details are
 * derived for a local MailSite submission as the reserved bot account
 * rather than read from the external relay fields. These cases check
 * the derived host, port, login, sender, transport security,
 * self-signed acceptance, and the absence of a stored password, and
 * that the external route still uses the configured relay fields.
 *
 * @author Chris Pollett
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
class OutboundMailClientTest extends UnitTest
{
    /**
     * No setup is needed; the factory is a pure function of config.
     */
    public function setUp()
    {
    }
    /**
     * No teardown is needed.
     */
    public function tearDown()
    {
    }
    /**
     * The bot route connects to the local MailSite on the submission
     * port.
     */
    public function botRouteUsesLocalSubmissionTestCase()
    {
        $client = MailSiteFactory::outboundSmtpClient(true);
        $this->assertEqual($client->server, "localhost",
            "bot route connects to localhost");
        $this->assertEqual($client->port, C\MAIL_SUBMISSION_PORT,
            "bot route uses the submission port");
    }
    /**
     * The bot route logs in and sends as the reserved bot account.
     */
    public function botRouteSendsAsBotTestCase()
    {
        $client = MailSiteFactory::outboundSmtpClient(true);
        $this->assertEqual($client->login, "bot",
            "bot route logs in as bot");
        $this->assertEqual(strtok($client->sender_email, "@"), "bot",
            "bot route sends from the bot address");
    }
    /**
     * The bot route uses STARTTLS and accepts the local self-signed
     * certificate.
     */
    public function botRouteUsesStarttlsTestCase()
    {
        $client = MailSiteFactory::outboundSmtpClient(true);
        $this->assertEqual($client->secure, "starttls",
            "bot route secures with STARTTLS");
        $this->assertTrue($client->allow_self_signed,
            "bot route accepts the local certificate");
    }
    /**
     * The bot route stores no password; the secret is minted at login.
     */
    public function botRouteHasNoStoredPasswordTestCase()
    {
        $client = MailSiteFactory::outboundSmtpClient(true);
        $this->assertEqual($client->password, "",
            "bot route carries no stored password");
    }
    /**
     * The external route uses the configured relay fields.
     */
    public function externalRouteUsesConfiguredRelayTestCase()
    {
        $client = MailSiteFactory::outboundSmtpClient(false);
        $this->assertEqual($client->server, C\MAIL_SERVER,
            "external route uses the configured server");
        $this->assertEqual($client->login, C\MAIL_USERNAME,
            "external route uses the configured username");
    }
    /**
     * The bot local part is the name before the "@", or the whole
     * value when the sender has no domain.
     */
    public function botLocalPartFromSenderTestCase()
    {
        $this->assertEqual(
            MailSiteFactory::botLocalPart("no_reply@example.com"),
            "no_reply", "local part of a full sender address");
        $this->assertEqual(MailSiteFactory::botLocalPart("bot"),
            "bot", "bare sender name is its own local part");
    }
    /**
     * The bot address keeps a full sender address as is and appends a
     * domain to a bare sender name.
     */
    public function botAddressFromSenderTestCase()
    {
        $this->assertEqual(
            MailSiteFactory::botAddress("no_reply@example.com"),
            "no_reply@example.com", "full sender used as is");
        $this->assertEqual(
            strtok(MailSiteFactory::botAddress("bot"), "@"), "bot",
            "bare sender name gets a domain appended");
    }
}
X