<?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\UnitTest;
use seekquarry\yioop\models\MailSuppressionModel;
use seekquarry\yioop\models\ProfileModel;
use seekquarry\yioop\models\datasources\Sqlite3Manager;
/**
* Tests the site-wide mail suppression list: that an address can be added
* and found, that matching ignores case, that an address can be removed,
* and that empty input is rejected rather than stored.
*
* @author Chris Pollett
*/
class MailSuppressionModelTest extends UnitTest
{
/**
* Throwaway SQLite database holding the suppression table
* @var object
*/
public $db;
/**
* File path of the throwaway database
* @var string
*/
public $db_path;
/**
* MailSuppressionModel pointed at the throwaway database
* @var object
*/
public $model;
/**
* Builds a throwaway database with an empty MAIL_SUPPRESSION table and
* a model wired to use it.
*/
public function setUp()
{
$tag = getmypid() . "_" . random_int(1000, 9999);
$this->db_path = C\WORK_DIRECTORY . "/temp/mail_suppress_$tag.db";
$this->db = new Sqlite3Manager();
$this->db->connect("", "", "", $this->db_path);
/* Build the table from ProfileModel's definition, the same one the
live database uses, so this test tracks any schema change rather
than a hand-copied CREATE TABLE that could drift. */
$dbinfo = ["DBMS" => "Sqlite3", "DB_HOST" => ""];
$profile = new ProfileModel(C\DB_NAME, false);
$profile->initializeSql($this->db, $dbinfo);
$this->db->execute($profile->create_statements['MAIL_SUPPRESSION']);
$this->db->execute("CREATE UNIQUE INDEX MAIL_SUPPRESSION_IDX ON
MAIL_SUPPRESSION (EMAIL)");
$this->model = new MailSuppressionModel(C\DB_NAME, false);
$this->model->db = $this->db;
}
/**
* Removes the throwaway database.
*/
public function tearDown()
{
if ($this->db) {
$this->db->disconnect();
/* Evict this test's own handle (keyed by file path) so a
reused scratch-file name in a later test opens fresh
rather than reusing this still-cached connection; a plain
disconnect does not evict. Shared handles are untouched. */
unset(Sqlite3Manager::$active_connections[
$this->db->connect_string]);
}
if ($this->db_path && file_exists($this->db_path)) {
unlink($this->db_path);
}
}
/**
* An address is not suppressed until added, is found once added, and a
* second add reports that nothing new was stored.
*/
public function suppressAndCheckTestCase()
{
$this->assertFalse($this->model->isSuppressed("a@b.com"),
"an unknown address is not suppressed");
$this->assertTrue($this->model->suppress("a@b.com"),
"adding a new address reports a row was stored");
$this->assertTrue($this->model->isSuppressed("a@b.com"),
"the added address is now suppressed");
$this->assertFalse($this->model->suppress("a@b.com"),
"adding the same address again stores nothing");
}
/**
* Matching an address ignores letter case in both directions.
*/
public function caseInsensitiveTestCase()
{
$this->model->suppress("Foo@Bar.com");
$this->assertTrue($this->model->isSuppressed("foo@bar.com"),
"a lower-case spelling matches the stored address");
$this->assertTrue($this->model->isSuppressed("FOO@BAR.COM"),
"an upper-case spelling matches the stored address");
}
/**
* A removed address is no longer suppressed, and removal ignores case.
*/
public function unsuppressTestCase()
{
$this->model->suppress("x@y.com");
$this->model->unsuppress("X@Y.COM");
$this->assertFalse($this->model->isSuppressed("x@y.com"),
"a removed address is no longer suppressed");
}
/**
* Empty or blank input is rejected rather than stored.
*/
public function emptyEmailTestCase()
{
$this->assertFalse($this->model->isSuppressed(""),
"an empty address is never suppressed");
$this->assertFalse($this->model->suppress(""),
"an empty address is not stored");
$this->assertFalse($this->model->suppress(" "),
"a blank address is not stored");
}
}