Files
newznab-tmux/tests/Feature/CbpCleanupServiceTest.php
T
2026-05-06 10:20:05 +02:00

284 lines
9.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Enums\CollectionFileCheckStatus;
use App\Models\Release;
use App\Services\CollectionCleanupService;
use App\Services\Nzb\NzbService;
use App\Services\ReleaseCleaningService;
use App\Services\ReleaseCreationService;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class CbpCleanupServiceTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['database.default' => 'sqlite', 'database.connections.sqlite.database' => ':memory:']);
DB::purge();
DB::reconnect();
DB::connection()->getPdo()->sqliteCreateFunction('UNIX_TIMESTAMP', static fn (?string $value): int => strtotime((string) $value));
$this->createTables();
$this->seedSettings();
}
public function test_retention_cleanup_deletes_parts_binaries_and_collections_without_fk_cascades(): void
{
DB::table('collections')->insert([
'id' => 100,
'subject' => 'Retention.Release',
'fromname' => 'poster@example.com',
'date' => now()->subHours(10)->format('Y-m-d H:i:s'),
'dateadded' => now()->subHours(10)->format('Y-m-d H:i:s'),
'added' => now()->subHours(10)->format('Y-m-d H:i:s'),
'xref' => 'alt.test:123',
'groups_id' => 1,
'totalfiles' => 1,
'filesize' => 500,
'filecheck' => CollectionFileCheckStatus::Sized->value,
'collectionhash' => 'retention-hash',
'collection_regexes_id' => 0,
'releases_id' => null,
'noise' => '',
]);
DB::table('binaries')->insert([
'id' => 1000,
'name' => 'Retention.Release.par2',
'collections_id' => 100,
'totalparts' => 1,
]);
DB::table('parts')->insert([
'binaries_id' => 1000,
'number' => 1,
'messageid' => '<retention-1@example.com>',
'partnumber' => 1,
'size' => 10,
]);
app(CollectionCleanupService::class)->deleteFinishedAndOrphans(false);
$this->assertSame(0, DB::table('parts')->count());
$this->assertSame(0, DB::table('binaries')->count());
$this->assertSame(0, DB::table('collections')->count());
}
public function test_nzb_creation_cleans_up_collection_binary_and_parts_explicitly(): void
{
DB::table('releases')->insert([
'id' => 1,
'name' => 'Nzb.Release',
'searchname' => 'Nzb.Release',
'totalpart' => 1,
'groups_id' => 1,
'adddate' => now()->format('Y-m-d H:i:s'),
'guid' => str_repeat('a', 36),
'leftguid' => 'a',
'postdate' => now()->format('Y-m-d H:i:s'),
'fromname' => 'poster@example.com',
'size' => 500,
'passwordstatus' => 0,
'haspreview' => -1,
'categories_id' => 1,
'nfostatus' => -1,
'nzbstatus' => NzbService::NZB_NONE,
'isrenamed' => 1,
'iscategorized' => 1,
'predb_id' => 0,
'source' => null,
'nzb_guid' => null,
]);
DB::table('collections')->insert([
'id' => 200,
'subject' => 'Nzb.Release',
'fromname' => 'poster@example.com',
'date' => now()->subHours(1)->format('Y-m-d H:i:s'),
'dateadded' => now()->subHours(1)->format('Y-m-d H:i:s'),
'added' => now()->subHours(1)->format('Y-m-d H:i:s'),
'xref' => 'alt.test:200',
'groups_id' => 1,
'totalfiles' => 1,
'filesize' => 500,
'filecheck' => CollectionFileCheckStatus::Inserted->value,
'collectionhash' => 'nzb-hash',
'collection_regexes_id' => 0,
'releases_id' => 1,
'noise' => '',
]);
DB::table('binaries')->insert([
'id' => 2000,
'name' => 'Nzb.Release yEnc',
'collections_id' => 200,
'totalparts' => 1,
]);
DB::table('parts')->insert([
'binaries_id' => 2000,
'number' => 1,
'messageid' => '<nzb-1@example.com>',
'partnumber' => 1,
'size' => 10,
]);
$release = Release::query()->findOrFail(1);
$release->setRelation('category', (object) ['title' => 'Misc', 'parent' => (object) ['title' => 'Other']]);
$written = app(NzbService::class)->writeNzbForReleaseId($release);
$this->assertTrue($written);
$this->assertSame(0, DB::table('parts')->count());
$this->assertSame(0, DB::table('binaries')->count());
$this->assertSame(0, DB::table('collections')->count());
$this->assertSame(1, (int) DB::table('releases')->where('id', 1)->value('nzbstatus'));
}
public function test_duplicate_release_path_cleans_up_collection_binary_and_parts(): void
{
DB::table('releases')->insert([
'id' => 2,
'name' => 'Duplicate.Release',
'searchname' => 'Duplicate.Release',
'totalpart' => 1,
'groups_id' => 1,
'adddate' => now()->format('Y-m-d H:i:s'),
'guid' => str_repeat('b', 36),
'leftguid' => 'b',
'postdate' => now()->format('Y-m-d H:i:s'),
'fromname' => 'poster@example.com',
'size' => 1000,
'passwordstatus' => 0,
'haspreview' => -1,
'categories_id' => 1,
'nfostatus' => -1,
'nzbstatus' => NzbService::NZB_NONE,
'isrenamed' => 1,
'iscategorized' => 1,
'predb_id' => 0,
'source' => null,
'nzb_guid' => null,
]);
DB::table('collections')->insert([
'id' => 300,
'subject' => 'Duplicate.Release',
'fromname' => 'poster@example.com',
'date' => now()->subHours(1)->format('Y-m-d H:i:s'),
'dateadded' => now()->subHours(1)->format('Y-m-d H:i:s'),
'added' => now()->subHours(1)->format('Y-m-d H:i:s'),
'xref' => 'alt.test:300',
'groups_id' => 1,
'totalfiles' => 1,
'filesize' => 1000,
'filecheck' => CollectionFileCheckStatus::Sized->value,
'collectionhash' => 'duplicate-hash',
'collection_regexes_id' => 0,
'releases_id' => null,
'noise' => '',
]);
DB::table('binaries')->insert([
'id' => 3000,
'name' => 'Duplicate.Release yEnc',
'collections_id' => 300,
'totalparts' => 1,
]);
DB::table('parts')->insert([
'binaries_id' => 3000,
'number' => 1,
'messageid' => '<duplicate-1@example.com>',
'partnumber' => 1,
'size' => 10,
]);
$service = new ReleaseCreationService(
app(ReleaseCleaningService::class),
app(CollectionCleanupService::class)
);
$result = $service->createReleases(null, 10, false);
$this->assertSame(['added' => 0, 'dupes' => 1], $result);
$this->assertSame(0, DB::table('parts')->count());
$this->assertSame(0, DB::table('binaries')->count());
$this->assertSame(0, DB::table('collections')->count());
}
private function seedSettings(): void
{
$settings = [
'partretentionhours' => '1',
'nzbsplitlevel' => '1',
'check_passworded_rars' => '0',
'categorizeforeign' => '1',
'catwebdl' => '1',
];
foreach ($settings as $name => $value) {
DB::table('settings')->insert(['name' => $name, 'value' => $value]);
}
}
private function createTables(): void
{
DB::statement('CREATE TABLE settings (name VARCHAR(255) PRIMARY KEY, value TEXT)');
DB::statement('CREATE TABLE usenet_groups (id INTEGER PRIMARY KEY, name VARCHAR(255))');
DB::statement('CREATE TABLE categories (id INTEGER PRIMARY KEY, title VARCHAR(255), parent_categories_id INTEGER NULL)');
DB::statement('CREATE TABLE releases (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
searchname VARCHAR(255),
totalpart INTEGER,
groups_id INTEGER,
adddate DATETIME NULL,
guid VARCHAR(64),
leftguid VARCHAR(1),
postdate DATETIME NULL,
fromname VARCHAR(255),
size INTEGER,
passwordstatus INTEGER,
haspreview INTEGER,
categories_id INTEGER,
nfostatus INTEGER,
nzbstatus INTEGER,
isrenamed INTEGER,
iscategorized INTEGER,
predb_id INTEGER,
source VARCHAR(255) NULL,
nzb_guid BLOB NULL
)');
DB::statement('CREATE TABLE collections (
id INTEGER PRIMARY KEY,
subject VARCHAR(255),
fromname VARCHAR(255),
date DATETIME NULL,
dateadded DATETIME NULL,
added DATETIME NULL,
xref TEXT,
groups_id INTEGER,
totalfiles INTEGER,
filesize INTEGER,
filecheck INTEGER,
collectionhash VARCHAR(255),
collection_regexes_id INTEGER,
releases_id INTEGER NULL,
noise VARCHAR(64)
)');
DB::statement('CREATE TABLE binaries (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
collections_id INTEGER,
totalparts INTEGER
)');
DB::statement('CREATE TABLE parts (
binaries_id INTEGER,
number INTEGER,
messageid VARCHAR(255),
partnumber INTEGER,
size INTEGER
)');
DB::table('usenet_groups')->insert(['id' => 1, 'name' => 'alt.test']);
DB::table('categories')->insert(['id' => 1, 'title' => 'Misc', 'parent_categories_id' => null]);
}
}