mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 04:01:24 +00:00
312 lines
11 KiB
PHP
312 lines
11 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Services\AdultProcessing\AdultProcessingPassable;
|
|
use App\Services\AdultProcessing\AdultProcessingPipeline;
|
|
use App\Services\AdultProcessing\AdultProcessingResult;
|
|
use App\Services\AdultProcessing\AdultReleaseContext;
|
|
use App\Services\AdultProcessing\Pipes\AbstractAdultProviderPipe;
|
|
use App\Services\AdultProcessing\Pipes\AdePipe;
|
|
use App\Services\AdultProcessing\Pipes\AdmPipe;
|
|
use App\Services\AdultProcessing\Pipes\AebnPipe;
|
|
use App\Services\AdultProcessing\Pipes\HotmoviesPipe;
|
|
use App\Services\AdultProcessing\Pipes\PoppornPipe;
|
|
use Closure;
|
|
use Tests\TestCase;
|
|
|
|
class AdultProcessingPipelineTest extends TestCase
|
|
{
|
|
/**
|
|
* Test that the pipeline can be instantiated with default pipes.
|
|
*/
|
|
public function test_pipeline_can_be_instantiated(): void
|
|
{
|
|
$pipeline = new AdultProcessingPipeline();
|
|
|
|
$this->assertInstanceOf(AdultProcessingPipeline::class, $pipeline);
|
|
$this->assertCount(5, $pipeline->getPipes());
|
|
}
|
|
|
|
/**
|
|
* Test that pipes are ordered by priority.
|
|
*/
|
|
public function test_pipes_are_ordered_by_priority(): void
|
|
{
|
|
$pipeline = new AdultProcessingPipeline();
|
|
$pipes = $pipeline->getPipes()->values();
|
|
|
|
// AEBN should be first (priority 10)
|
|
$this->assertInstanceOf(AebnPipe::class, $pipes[0]);
|
|
// PopPorn should be second (priority 20)
|
|
$this->assertInstanceOf(PoppornPipe::class, $pipes[1]);
|
|
// ADM should be third (priority 30)
|
|
$this->assertInstanceOf(AdmPipe::class, $pipes[2]);
|
|
// ADE should be fourth (priority 40)
|
|
$this->assertInstanceOf(AdePipe::class, $pipes[3]);
|
|
// HotMovies should be last (priority 50)
|
|
$this->assertInstanceOf(HotmoviesPipe::class, $pipes[4]);
|
|
}
|
|
|
|
/**
|
|
* Test that a pipe can be added to the pipeline.
|
|
*/
|
|
public function test_can_add_pipe_to_pipeline(): void
|
|
{
|
|
$pipeline = new AdultProcessingPipeline([]);
|
|
|
|
$this->assertCount(5, $pipeline->getPipes()); // Default pipes
|
|
|
|
// Create a custom pipe with high priority
|
|
$customPipe = new class extends AbstractAdultProviderPipe {
|
|
protected int $priority = 5;
|
|
|
|
public function getName(): string
|
|
{
|
|
return 'custom';
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return 'Custom Provider';
|
|
}
|
|
|
|
protected function getBaseUrl(): string
|
|
{
|
|
return 'https://example.com';
|
|
}
|
|
|
|
protected function process(AdultProcessingPassable $passable): AdultProcessingResult
|
|
{
|
|
return AdultProcessingResult::notFound($this->getName());
|
|
}
|
|
|
|
protected function search(string $movie): array|false
|
|
{
|
|
return false;
|
|
}
|
|
|
|
protected function getMovieInfo(): array|false
|
|
{
|
|
return false;
|
|
}
|
|
};
|
|
|
|
$pipeline->addPipe($customPipe);
|
|
|
|
$this->assertCount(6, $pipeline->getPipes());
|
|
}
|
|
|
|
/**
|
|
* Test AdultReleaseContext creation from title.
|
|
*/
|
|
public function test_release_context_from_title(): void
|
|
{
|
|
$context = AdultReleaseContext::fromTitle('Test Movie Title');
|
|
|
|
$this->assertEquals(0, $context->releaseId);
|
|
$this->assertEquals('Test Movie Title', $context->searchName);
|
|
$this->assertEquals('Test Movie Title', $context->cleanTitle);
|
|
$this->assertNull($context->guid);
|
|
}
|
|
|
|
/**
|
|
* Test AdultReleaseContext creation from release array.
|
|
*/
|
|
public function test_release_context_from_release(): void
|
|
{
|
|
$release = [
|
|
'id' => 123,
|
|
'searchname' => 'Test.Movie.Title.XXX.2023',
|
|
'guid' => 'abc123',
|
|
];
|
|
|
|
$context = AdultReleaseContext::fromRelease($release, 'Test Movie Title');
|
|
|
|
$this->assertEquals(123, $context->releaseId);
|
|
$this->assertEquals('Test.Movie.Title.XXX.2023', $context->searchName);
|
|
$this->assertEquals('Test Movie Title', $context->cleanTitle);
|
|
$this->assertEquals('abc123', $context->guid);
|
|
}
|
|
|
|
/**
|
|
* Test AdultProcessingResult creation methods.
|
|
*/
|
|
public function test_processing_result_creation(): void
|
|
{
|
|
// Test matched result
|
|
$matchedResult = AdultProcessingResult::matched(
|
|
'Test Movie',
|
|
'aebn',
|
|
['boxcover' => 'http://example.com/cover.jpg']
|
|
);
|
|
$this->assertEquals(AdultProcessingResult::STATUS_MATCHED, $matchedResult->status);
|
|
$this->assertTrue($matchedResult->isMatched());
|
|
$this->assertFalse($matchedResult->shouldContinueProcessing());
|
|
$this->assertEquals('http://example.com/cover.jpg', $matchedResult->getBoxCover());
|
|
|
|
// Test not found result
|
|
$notFoundResult = AdultProcessingResult::notFound('aebn');
|
|
$this->assertEquals(AdultProcessingResult::STATUS_NOT_FOUND, $notFoundResult->status);
|
|
$this->assertFalse($notFoundResult->isMatched());
|
|
$this->assertTrue($notFoundResult->shouldContinueProcessing());
|
|
|
|
// Test skipped result
|
|
$skippedResult = AdultProcessingResult::skipped('Provider unavailable', 'aebn');
|
|
$this->assertEquals(AdultProcessingResult::STATUS_SKIPPED, $skippedResult->status);
|
|
$this->assertFalse($skippedResult->isMatched());
|
|
|
|
// Test pending result
|
|
$pendingResult = AdultProcessingResult::pending();
|
|
$this->assertEquals(AdultProcessingResult::STATUS_PENDING, $pendingResult->status);
|
|
$this->assertFalse($pendingResult->isMatched());
|
|
}
|
|
|
|
/**
|
|
* Test AdultProcessingPassable behavior.
|
|
*/
|
|
public function test_processing_passable_behavior(): void
|
|
{
|
|
$context = AdultReleaseContext::fromTitle('Test Movie');
|
|
$passable = new AdultProcessingPassable($context, true, 'test_cookie');
|
|
|
|
$this->assertEquals('Test Movie', $passable->getCleanTitle());
|
|
$this->assertEquals('test_cookie', $passable->getCookie());
|
|
$this->assertFalse($passable->shouldStopProcessing());
|
|
|
|
// Update with a matched result
|
|
$result = AdultProcessingResult::matched('Test Movie', 'aebn', []);
|
|
$passable->updateResult($result, 'aebn');
|
|
|
|
$this->assertTrue($passable->shouldStopProcessing());
|
|
$this->assertEquals('aebn', $passable->result->providerName);
|
|
}
|
|
|
|
/**
|
|
* Test individual pipe name and priority.
|
|
*/
|
|
public function test_pipe_names_and_priorities(): void
|
|
{
|
|
$aebn = new AebnPipe();
|
|
$this->assertEquals('aebn', $aebn->getName());
|
|
$this->assertEquals('Adult Entertainment Broadcast Network', $aebn->getDisplayName());
|
|
$this->assertEquals(10, $aebn->getPriority());
|
|
|
|
$popporn = new PoppornPipe();
|
|
$this->assertEquals('pop', $popporn->getName());
|
|
$this->assertEquals('PopPorn', $popporn->getDisplayName());
|
|
$this->assertEquals(20, $popporn->getPriority());
|
|
|
|
$adm = new AdmPipe();
|
|
$this->assertEquals('adm', $adm->getName());
|
|
$this->assertEquals('Adult DVD Marketplace', $adm->getDisplayName());
|
|
$this->assertEquals(30, $adm->getPriority());
|
|
|
|
$ade = new AdePipe();
|
|
$this->assertEquals('ade', $ade->getName());
|
|
$this->assertEquals('Adult DVD Empire', $ade->getDisplayName());
|
|
$this->assertEquals(40, $ade->getPriority());
|
|
|
|
$hotmovies = new HotmoviesPipe();
|
|
$this->assertEquals('hotm', $hotmovies->getName());
|
|
$this->assertEquals('HotMovies', $hotmovies->getDisplayName());
|
|
$this->assertEquals(50, $hotmovies->getPriority());
|
|
}
|
|
|
|
/**
|
|
* Test passable to array conversion with debug info.
|
|
*/
|
|
public function test_passable_to_array_with_debug(): void
|
|
{
|
|
$context = AdultReleaseContext::fromRelease([
|
|
'id' => 123,
|
|
'searchname' => 'Test.Movie.XXX',
|
|
], 'Test Movie');
|
|
|
|
$passable = new AdultProcessingPassable($context, true);
|
|
|
|
$result = AdultProcessingResult::matched('Test Movie', 'aebn', [
|
|
'boxcover' => 'http://example.com/cover.jpg',
|
|
]);
|
|
$passable->updateResult($result, 'aebn');
|
|
|
|
$array = $passable->toArray();
|
|
|
|
$this->assertEquals('matched', $array['status']);
|
|
$this->assertEquals('Test Movie', $array['title']);
|
|
$this->assertEquals('aebn', $array['provider']);
|
|
$this->assertArrayHasKey('debug', $array);
|
|
$this->assertEquals(123, $array['debug']['release_id']);
|
|
$this->assertEquals('Test.Movie.XXX', $array['debug']['search_name']);
|
|
$this->assertEquals('Test Movie', $array['debug']['clean_title']);
|
|
}
|
|
|
|
/**
|
|
* Test that echo output can be disabled on pipes.
|
|
*/
|
|
public function test_pipe_echo_output_can_be_disabled(): void
|
|
{
|
|
$pipe = new AebnPipe();
|
|
$pipe->setEchoOutput(false);
|
|
|
|
// This should not throw any exceptions
|
|
$this->assertInstanceOf(AebnPipe::class, $pipe);
|
|
}
|
|
|
|
/**
|
|
* Test similarity calculation for title matching.
|
|
*/
|
|
public function test_title_similarity_calculation(): void
|
|
{
|
|
$pipe = new class extends AbstractAdultProviderPipe {
|
|
public function getName(): string
|
|
{
|
|
return 'test';
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return 'Test';
|
|
}
|
|
|
|
protected function getBaseUrl(): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function process(AdultProcessingPassable $passable): AdultProcessingResult
|
|
{
|
|
return AdultProcessingResult::pending();
|
|
}
|
|
|
|
protected function search(string $movie): array|false
|
|
{
|
|
return false;
|
|
}
|
|
|
|
protected function getMovieInfo(): array|false
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public function publicCalculateSimilarity(string $search, string $result): float
|
|
{
|
|
return $this->calculateSimilarity($search, $result);
|
|
}
|
|
};
|
|
|
|
// Exact match should be 100%
|
|
$similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Test Movie');
|
|
$this->assertGreaterThan(99, $similarity);
|
|
|
|
// Similar titles should have high similarity
|
|
$similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Test Movie 2023');
|
|
$this->assertGreaterThan(80, $similarity);
|
|
|
|
// Different titles should have lower similarity
|
|
$similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Completely Different Title');
|
|
$this->assertLessThan(50, $similarity);
|
|
}
|
|
}
|
|
|