mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 17:01:16 +00:00
Respect imported nzb category
This commit is contained in:
@@ -5,10 +5,13 @@ declare(strict_types=1);
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Enums\NzbImportStatus;
|
||||
use App\Models\Category;
|
||||
use App\Services\Nzb\NzbImportService;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use PDO;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Tests\TestCase;
|
||||
@@ -68,6 +71,12 @@ final class NzbImportServiceTest extends TestCase
|
||||
DB::purge();
|
||||
DB::reconnect();
|
||||
Cache::flush();
|
||||
|
||||
Schema::create('categories', function (Blueprint $table): void {
|
||||
$table->integer('id')->primary();
|
||||
$table->string('title');
|
||||
$table->integer('status');
|
||||
});
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
@@ -228,6 +237,66 @@ final class NzbImportServiceTest extends TestCase
|
||||
$this->assertSame($expected, $service->deriveForTest($input));
|
||||
}
|
||||
|
||||
public function test_nzb_category_metadata_resolves_active_id_and_unique_case_insensitive_title(): void
|
||||
{
|
||||
$this->insertCategory(2040, 'HD', Category::STATUS_ACTIVE);
|
||||
$this->insertCategory(3040, 'Lossless', Category::STATUS_ACTIVE);
|
||||
|
||||
$this->assertSame(2040, $this->resolveNzbCategory('<meta type="category"> 2040 </meta>'));
|
||||
$this->assertSame(3040, $this->resolveNzbCategory('<meta type="CATEGORY"> lossLESS </meta>'));
|
||||
$this->assertSame(2040, $this->resolveNzbCategory(
|
||||
'<meta type="category">2040</meta>',
|
||||
' xmlns="http://www.newzbin.com/DTD/2003/nzb"'
|
||||
));
|
||||
}
|
||||
|
||||
public function test_nzb_category_metadata_rejects_unknown_inactive_disabled_and_ambiguous_values(): void
|
||||
{
|
||||
$this->insertCategory(2040, 'HD', Category::STATUS_ACTIVE);
|
||||
$this->insertCategory(3040, 'Lossless', Category::STATUS_INACTIVE);
|
||||
$this->insertCategory(5040, 'HD', Category::STATUS_ACTIVE);
|
||||
$this->insertCategory(6040, 'X264', Category::STATUS_DISABLED);
|
||||
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="category">9999</meta>'));
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="category">3040</meta>'));
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="category">X264</meta>'));
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="category">HD</meta>'));
|
||||
}
|
||||
|
||||
public function test_nzb_category_metadata_rejects_conflicting_matches(): void
|
||||
{
|
||||
$this->insertCategory(2040, 'Movie HD', Category::STATUS_ACTIVE);
|
||||
$this->insertCategory(5040, 'TV HD', Category::STATUS_ACTIVE);
|
||||
|
||||
$this->assertNull($this->resolveNzbCategory(
|
||||
'<meta type="category">2040</meta><meta type="category">TV HD</meta>'
|
||||
));
|
||||
}
|
||||
|
||||
public function test_nzb_category_metadata_falls_back_when_category_is_missing_or_blank(): void
|
||||
{
|
||||
$this->assertNull($this->resolveNzbXml('<nzb><file subject="example" /></nzb>'));
|
||||
$this->assertNull($this->resolveNzbCategory(''));
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="category"> </meta>'));
|
||||
$this->assertNull($this->resolveNzbCategory('<meta type="password">secret</meta>'));
|
||||
}
|
||||
|
||||
public function test_compressed_nzb_write_returns_false_for_an_unwritable_destination(): void
|
||||
{
|
||||
$service = new class(['Browser' => true]) extends NzbImportService
|
||||
{
|
||||
public function writeForTest(string $path, string $contents): bool
|
||||
{
|
||||
return $this->writeCompressedNzb($path, $contents);
|
||||
}
|
||||
};
|
||||
|
||||
$path = sys_get_temp_dir().'/missing-'.bin2hex(random_bytes(5)).'/release.nzb.gz';
|
||||
|
||||
$this->assertFalse($service->writeForTest($path, '<nzb />'));
|
||||
$this->assertFileDoesNotExist($path);
|
||||
}
|
||||
|
||||
private function makeNzbFile(string $suffix): string
|
||||
{
|
||||
$path = sys_get_temp_dir().'/'.$suffix.'-'.bin2hex(random_bytes(5)).'.nzb';
|
||||
@@ -236,6 +305,36 @@ final class NzbImportServiceTest extends TestCase
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function insertCategory(int $id, string $title, int $status): void
|
||||
{
|
||||
DB::table('categories')->insert([
|
||||
'id' => $id,
|
||||
'title' => $title,
|
||||
'status' => $status,
|
||||
]);
|
||||
}
|
||||
|
||||
private function resolveNzbCategory(string $headMetadata, string $nzbAttributes = ''): ?int
|
||||
{
|
||||
return $this->resolveNzbXml("<nzb{$nzbAttributes}><head>{$headMetadata}</head></nzb>");
|
||||
}
|
||||
|
||||
private function resolveNzbXml(string $xml): ?int
|
||||
{
|
||||
$service = new class(['Browser' => true]) extends NzbImportService
|
||||
{
|
||||
public function resolveForTest(\SimpleXMLElement $nzb): ?int
|
||||
{
|
||||
return $this->resolveNzbCategoryId($nzb);
|
||||
}
|
||||
};
|
||||
|
||||
$nzb = simplexml_load_string($xml);
|
||||
$this->assertInstanceOf(\SimpleXMLElement::class, $nzb);
|
||||
|
||||
return $service->resolveForTest($nzb);
|
||||
}
|
||||
|
||||
private function setEnvironmentValue(string $key, ?string $value): void
|
||||
{
|
||||
if ($value === null) {
|
||||
|
||||
@@ -5,8 +5,8 @@ declare(strict_types=1);
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Services\Nzb\NzbService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class NzbServicePathResolutionTest extends TestCase
|
||||
{
|
||||
@@ -120,6 +120,35 @@ final class NzbServicePathResolutionTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function test_build_nzb_path_creates_group_writable_setgid_directories_despite_umask(): void
|
||||
{
|
||||
$tempDir = sys_get_temp_dir().'/nzb-path-permissions-'.uniqid('', true);
|
||||
$basePath = $tempDir.'/';
|
||||
mkdir($basePath, 0775, true);
|
||||
$previousUmask = umask(0022);
|
||||
|
||||
try {
|
||||
$service = $this->makeServiceWithoutConstructor();
|
||||
\Closure::bind(
|
||||
function (string $path): void {
|
||||
$this->siteNzbPath = $path;
|
||||
},
|
||||
$service,
|
||||
NzbService::class
|
||||
)($basePath);
|
||||
|
||||
$path = $service->buildNzbPath('4aabfe07-daff-4d28-9d1d-d2a4ab7b6511', 4, true);
|
||||
|
||||
$this->assertSame($basePath.'4/a/a/b/', $path);
|
||||
foreach ([$basePath.'4', $basePath.'4/a', $basePath.'4/a/a', $basePath.'4/a/a/b'] as $directory) {
|
||||
$this->assertSame(02775, fileperms($directory) & 07777);
|
||||
}
|
||||
} finally {
|
||||
umask($previousUmask);
|
||||
$this->deleteDirectory($tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private function makeServiceWithoutConstructor(): NzbService
|
||||
{
|
||||
return (new ReflectionClass(NzbService::class))->newInstanceWithoutConstructor();
|
||||
|
||||
Reference in New Issue
Block a user