feat: download data preview modal
This commit is contained in:
3
.env.test
Normal file
3
.env.test
Normal file
@@ -0,0 +1,3 @@
|
||||
# define your env variables for the test env here
|
||||
KERNEL_CLASS='App\Kernel'
|
||||
APP_SECRET='$ecretf0rt3st'
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -19,3 +19,8 @@ bolt.db
|
||||
phpstan.neon
|
||||
###< phpstan/phpstan ###
|
||||
.php-cs-fixer.cache
|
||||
|
||||
###> phpunit/phpunit ###
|
||||
/phpunit.xml
|
||||
/.phpunit.cache/
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
4
assets/bootstrap.js
vendored
4
assets/bootstrap.js
vendored
@@ -1,5 +1,7 @@
|
||||
import PreviewContentDialog from "./components/preview-content-dialog.js";
|
||||
import EpisodeContainer from './components/episode-container.js';
|
||||
import DownloadOptionTr from './components/download-option-tr.js';
|
||||
import DownloadListRow from './components/download-list-row.js';
|
||||
import MovieContainer from "./components/movie-container.js";
|
||||
|
||||
import { startStimulusApp } from '@symfony/stimulus-bundle';
|
||||
@@ -14,6 +16,8 @@ app.register('popover', Popover);
|
||||
app.register('dialog', Dialog);
|
||||
app.register('dropdown', Dropdown);
|
||||
|
||||
customElements.define('preview-content-dialog', PreviewContentDialog, {extends: 'dialog'});
|
||||
customElements.define('episode-container', EpisodeContainer);
|
||||
customElements.define('movie-container', MovieContainer);
|
||||
customElements.define('dl-tr', DownloadOptionTr, {extends: 'tr'});
|
||||
customElements.define('download-list-row', DownloadListRow, {extends: 'tr'});
|
||||
|
||||
110
assets/components/download-list-row.js
Normal file
110
assets/components/download-list-row.js
Normal file
@@ -0,0 +1,110 @@
|
||||
export default class DownloadListRow extends HTMLTableRowElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.downloadId = this.getAttribute('download-id');
|
||||
this.imdbId = this.getAttribute('imdb-id');
|
||||
this.mediaTitle = this.getAttribute('media-title');
|
||||
this.url = this.getAttribute('url');
|
||||
this.filename = this.getAttribute('filename');
|
||||
this.status = this.getAttribute('status');
|
||||
this.progress = this.getAttribute('progress');
|
||||
this.mediaType = this.getAttribute('media-type');
|
||||
this.episodeId = this.getAttribute('episode-id');
|
||||
this.createdAt = this.getAttribute('created-at');
|
||||
this.updatedAt = this.getAttribute('updated-at');
|
||||
|
||||
// this.previewContent = this.previewContent.bind(this);
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['download-id', 'imdb-id', 'media-title', 'url', 'filename', 'status', 'progress', 'media-type', 'episode-id', 'created-at', 'updated-at'];
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue !== newValue) {
|
||||
this[name] = newValue;
|
||||
this.setAttribute(name, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
previewContent() {
|
||||
return `
|
||||
<table class="table-auto flex flex-row">
|
||||
<thead>
|
||||
<tr class="flex flex-col">
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">ID</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">IMDB ID</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Title</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">URL</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Filename</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Status</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Progress</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Media Type</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Episode ID</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Created At</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-right whitespace-nowrap ">Updated At</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="flex flex-col">
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('download-id') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('imdb-id') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('media-title') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('url') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('filename') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('status') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('progress') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('media-type') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('episode-id') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('created-at') ?? "-"}</div>
|
||||
</th>
|
||||
<th class="px-4 py-2">
|
||||
<div class="text-left whitespace-nowrap font-normal">${this.getAttribute('updated-at') ?? "-"}</div>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
}
|
||||
35
assets/components/preview-content-dialog.js
Normal file
35
assets/components/preview-content-dialog.js
Normal file
@@ -0,0 +1,35 @@
|
||||
export default class PreviewContentDialog extends HTMLDialogElement {
|
||||
#headingEl;
|
||||
#contentEl;
|
||||
#closeBtnEl;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#headingEl = this.querySelector('.modal-heading');
|
||||
this.#contentEl = this.querySelector('.modal-content');
|
||||
this.#closeBtnEl = this.querySelector('.modal-close');
|
||||
|
||||
this.setHeading = this.setHeading.bind(this);
|
||||
this.setContent = this.setContent.bind(this);
|
||||
|
||||
document.addEventListener('showPreviewContentModal', (event) => {
|
||||
this.display(event.detail);
|
||||
});
|
||||
document.addEventListener('hidePreviewContentModal', (e) => this.close());
|
||||
this.#closeBtnEl.addEventListener('click', () => this.close());
|
||||
}
|
||||
|
||||
setHeading(heading) {
|
||||
this.#headingEl.innerHTML = heading;
|
||||
}
|
||||
|
||||
setContent(content) {
|
||||
this.#contentEl.innerHTML = content;
|
||||
}
|
||||
|
||||
display({ heading, content }) {
|
||||
this.setHeading(heading);
|
||||
this.setContent(content);
|
||||
this.showModal();
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,46 @@ export default class extends Controller {
|
||||
// Here you can add event listeners on the element or target elements,
|
||||
// add or remove classes, attributes, dispatch custom events, etc.
|
||||
// this.fooTarget.addEventListener('click', this._fooBar)
|
||||
// this.element.addEventListener('click', (event) => {
|
||||
// let previewContentModal = document.querySelector('#previewContentModal');
|
||||
// // previewContentModal.setHeading(event.target.dataset['title']);
|
||||
// // previewContentModal.setContent('<p>Testing this here thingy-ma-bob!</p>');
|
||||
// // previewContentModal.showModal();
|
||||
// let content, heading = ""
|
||||
// if (event.target.tagName !== "TR") {
|
||||
// content = event.target.parentElement.previewContent();
|
||||
// heading = event.target.parentElement.mediaTitle;
|
||||
// } else {
|
||||
// content = event.target.previewContent();
|
||||
// heading = event.target.mediaTitle;
|
||||
// }
|
||||
//
|
||||
// document.dispatchEvent(new CustomEvent('showPreviewContentModal', {detail: {heading: heading, content: content}}))
|
||||
// })
|
||||
}
|
||||
|
||||
downloadTargetConnected(target) {
|
||||
let downloads = this.element.querySelectorAll('tbody tr');
|
||||
if (downloads.length > 5) {
|
||||
target.classList.add('hidden');
|
||||
}
|
||||
|
||||
console.log(target)
|
||||
|
||||
downloads.forEach(download => {
|
||||
console.log(download)
|
||||
download.mediaTitle = download.getAttribute('media-title');
|
||||
download.addEventListener('click', (event) => {
|
||||
// let previewContentModal = document.querySelector('#previewContentModal');
|
||||
let content, heading = ""
|
||||
if (event.target.tagName !== "TR") {
|
||||
content = event.target.parentElement.previewContent();
|
||||
heading = event.target.parentElement.mediaTitle;
|
||||
} else {
|
||||
content = event.target.previewContent();
|
||||
heading = event.target.mediaTitle;
|
||||
}
|
||||
|
||||
document.dispatchEvent(new CustomEvent('showPreviewContentModal', {detail: {heading: heading, content: content}}))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pauseDownload(data) {
|
||||
|
||||
23
bin/phpunit
Executable file
23
bin/phpunit
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
|
||||
} else {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
}
|
||||
} else {
|
||||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
|
||||
}
|
||||
@@ -118,6 +118,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpunit/phpunit": "^12.3",
|
||||
"symfony/maker-bundle": "^1.62",
|
||||
"symfony/stopwatch": "7.3.*",
|
||||
"symfony/web-profiler-bundle": "7.3.*"
|
||||
|
||||
1564
composer.lock
generated
1564
composer.lock
generated
File diff suppressed because it is too large
Load Diff
44
phpunit.dist.xml
Normal file
44
phpunit.dist.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
failOnDeprecation="true"
|
||||
failOnNotice="true"
|
||||
failOnWarning="true"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
cacheDirectory=".phpunit.cache"
|
||||
>
|
||||
<php>
|
||||
<ini name="display_errors" value="1" />
|
||||
<ini name="error_reporting" value="-1" />
|
||||
<server name="APP_ENV" value="test" force="true" />
|
||||
<server name="SHELL_VERBOSITY" value="-1" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<source ignoreSuppressionOfDeprecations="true"
|
||||
ignoreIndirectDeprecations="true"
|
||||
restrictNotices="true"
|
||||
restrictWarnings="true"
|
||||
>
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
|
||||
<deprecationTrigger>
|
||||
<method>Doctrine\Deprecations\Deprecation::trigger</method>
|
||||
<method>Doctrine\Deprecations\Deprecation::delegateTriggerToBackend</method>
|
||||
<function>trigger_deprecation</function>
|
||||
</deprecationTrigger>
|
||||
</source>
|
||||
|
||||
<extensions>
|
||||
</extensions>
|
||||
</phpunit>
|
||||
@@ -47,6 +47,7 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
&& null !== $episode->season
|
||||
)
|
||||
;
|
||||
|
||||
$this->logger->info('> [MonitorTvShowHandler] Found ' . count($downloadedEpisodes) . ' downloaded episodes for title: ' . $monitor->getTitle());
|
||||
|
||||
// Compare against list from TMDB
|
||||
|
||||
15
symfony.lock
15
symfony.lock
@@ -86,6 +86,21 @@
|
||||
"phpstan.dist.neon"
|
||||
]
|
||||
},
|
||||
"phpunit/phpunit": {
|
||||
"version": "12.3",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "11.1",
|
||||
"ref": "c6658a60fc9d594805370eacdf542c3d6b5c0869"
|
||||
},
|
||||
"files": [
|
||||
".env.test",
|
||||
"phpunit.dist.xml",
|
||||
"tests/bootstrap.php",
|
||||
"bin/phpunit"
|
||||
]
|
||||
},
|
||||
"spomky-labs/pwa-bundle": {
|
||||
"version": "1.2.5"
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="{{ table_body_id }}" class="divide-y divide-gray-200 dark:divide-gray-50">
|
||||
<tbody id="{{ table_body_id }}" class="divide-y divide-gray-200 dark:divide-gray-50" data-download-list-target="download">
|
||||
{% if this.downloads.items|length > 0 %}
|
||||
{% for download in this.downloads.items %}
|
||||
<twig:DownloadListRow download="{{ download }}" isWidget="{{ isWidget }}" />
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<tr{{ attributes }} class="hover:bg-gray-200" id="ad_download_{{ download.id }}">
|
||||
<tr{{ attributes }} is="download-list-row" class="hover:bg-gray-200" id="ad_download_{{ download.id }}" data-title="{{ download.title }}"
|
||||
download-id="{{ download.id }}" imdb-id="{{ download.imdbId }}" media-title="{{ download.title }}" url="{{ download.url }}" filename="{{ download.filename }}" status="{{ download.status }}" progress="{{ download.progress }}" media-type="{{ download.mediaType }}" episode-id="{{ download.episodeId }}" created-at="{{ download.createdAt|date('m/d/Y g:i a') }}" updated-at="{{ download.updatedAt|date }}"
|
||||
data-filename="{{ download.filename }}" data-media-type="{{ download.mediaType }}" data-status="{{ download.status }}" data-progress="{{ download.progress }}"
|
||||
>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 truncate">
|
||||
{% if download.mediaType == "movies" %}
|
||||
{% set routeParams = {imdbId: download.imdbId, mediaType: download.mediaType} %}
|
||||
|
||||
10
templates/components/PreviewModal.html.twig
Normal file
10
templates/components/PreviewModal.html.twig
Normal file
@@ -0,0 +1,10 @@
|
||||
<dialog{{ attributes }} is="preview-content-dialog" class="py-3 px-4 w-full md:w-[50rem] rounded-md">
|
||||
<div class="flex flex-row justify-end">
|
||||
<twig:ux:icon name="ic:twotone-cancel" width="16.75px" height="16.75px" class="modal-close rounded-full align-middle text-red-600 hover:text-red-700" />
|
||||
</div>
|
||||
<h2 class="modal-heading mb-4 text-2xl font-bold">{{ heading|default('') }}</h2>
|
||||
|
||||
<div class="modal-content mb-4">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -15,4 +15,6 @@
|
||||
<twig:DownloadList type="complete" :isWidget="false" :perPage="10"></twig:DownloadList>
|
||||
</twig:Card>
|
||||
</div>
|
||||
|
||||
<twig:PreviewModal id="previewModal" />
|
||||
{% endblock %}
|
||||
|
||||
13
tests/Download/DownloadOptionEvaluatorTest.php
Normal file
13
tests/Download/DownloadOptionEvaluatorTest.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Download;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DownloadOptionEvaluatorTest extends TestCase
|
||||
{
|
||||
public function testEpisodeExists(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
178
tests/Monitor/MonitorTvShowHandlerTest.php
Normal file
178
tests/Monitor/MonitorTvShowHandlerTest.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Monitor;
|
||||
|
||||
use App\Base\Service\MediaFiles;
|
||||
use App\Monitor\Action\Command\MonitorTvShowCommand;
|
||||
use App\Monitor\Action\Handler\MonitorTvEpisodeHandler;
|
||||
use App\Monitor\Action\Handler\MonitorTvShowHandler;
|
||||
use App\Monitor\Action\Result\MonitorTvShowResult;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Tmdb;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class MonitorTvShowHandlerTest extends TestCase
|
||||
{
|
||||
private MonitorTvShowHandler $handler;
|
||||
private MonitorRepository $monitorRepository;
|
||||
private EntityManagerInterface $entityManager;
|
||||
private MonitorTvEpisodeHandler $episodeHandler;
|
||||
private MediaFiles $mediaFiles;
|
||||
private LoggerInterface $logger;
|
||||
private Tmdb $tmdb;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->monitorRepository = $this->createMock(MonitorRepository::class);
|
||||
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
||||
$this->episodeHandler = $this->createMock(MonitorTvEpisodeHandler::class);
|
||||
$this->mediaFiles = $this->createMock(MediaFiles::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->tmdb = $this->createMock(Tmdb::class);
|
||||
|
||||
$this->handler = new MonitorTvShowHandler(
|
||||
$this->monitorRepository,
|
||||
$this->entityManager,
|
||||
$this->episodeHandler,
|
||||
$this->mediaFiles,
|
||||
$this->logger,
|
||||
$this->tmdb
|
||||
);
|
||||
}
|
||||
|
||||
public function testEpisodeExists(): void
|
||||
{
|
||||
// Arrange
|
||||
$monitor = $this->createMock(Monitor::class);
|
||||
$monitor->method('getId')->willReturn(1);
|
||||
$monitor->method('getTmdbId')->willReturn('63770');
|
||||
$monitor->method('getSeason')->willReturn(10);
|
||||
$monitor->method('getTitle')->willReturn('The Late Show with Stephen Colbert');
|
||||
|
||||
$this->monitorRepository->expects($this->once())
|
||||
->method('find')
|
||||
->with(1)
|
||||
->willReturn($monitor);
|
||||
|
||||
$this->tmdb->expects($this->once())
|
||||
->method('seasonDetails')
|
||||
->with(63770, 10)
|
||||
->willReturn((object)['episodes' => [$this->getTmdbEpisode()]]);
|
||||
|
||||
$this->mediaFiles->expects($this->once())
|
||||
->method('findEpisodes')
|
||||
->willReturn($this->getDownloadedEpisodes());
|
||||
|
||||
// Act
|
||||
$command = new MonitorTvShowCommand(1);
|
||||
$result = $this->handler->handle($command);
|
||||
|
||||
// Assert
|
||||
$this->assertInstanceOf(MonitorTvShowResult::class, $result);
|
||||
$this->assertEquals('OK', $result->status);
|
||||
$this->assertTrue(isset($result->result['monitor']));
|
||||
$this->assertSame($monitor, $result->result['monitor']);
|
||||
}
|
||||
|
||||
public function testEpisodeDoesNotExist(): void
|
||||
{
|
||||
// Arrange
|
||||
$monitor = $this->createMock(Monitor::class);
|
||||
$monitor->method('getId')->willReturn(1);
|
||||
$monitor->method('getTmdbId')->willReturn(63770);
|
||||
$monitor->method('getSeason')->willReturn(10);
|
||||
$monitor->method('getTitle')->willReturn('The Late Show with Stephen Colbert');
|
||||
|
||||
$this->monitorRepository->expects($this->once())
|
||||
->method('find')
|
||||
->with(1)
|
||||
->willReturn($monitor);
|
||||
|
||||
$this->tmdb->expects($this->once())
|
||||
->method('seasonDetails')
|
||||
->with(63770, 10)
|
||||
->willReturn((object)['episodes' => []]);
|
||||
|
||||
$this->mediaFiles->expects($this->once())
|
||||
->method('findEpisodes')
|
||||
->willReturn([]);
|
||||
|
||||
// Act
|
||||
$command = new MonitorTvShowCommand(1);
|
||||
$result = $this->handler->handle($command);
|
||||
|
||||
// Assert
|
||||
$this->assertInstanceOf(MonitorTvShowResult::class, $result);
|
||||
$this->assertEquals('OK', $result->status);
|
||||
$this->assertTrue(isset($result->result['monitor']));
|
||||
$this->assertSame($monitor, $result->result['monitor']);
|
||||
}
|
||||
|
||||
public function testHandleWithInvalidMonitorId(): void
|
||||
{
|
||||
// Arrange
|
||||
$this->monitorRepository->expects($this->once())
|
||||
->method('find')
|
||||
->with(999)
|
||||
->willReturn(null);
|
||||
|
||||
// Act & Assert
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('Monitor not found');
|
||||
|
||||
$command = new MonitorTvShowCommand(999);
|
||||
$this->handler->handle($command);
|
||||
}
|
||||
|
||||
private function getTmdbEpisode(): array
|
||||
{
|
||||
return [
|
||||
"air_date" => "2016-05-13",
|
||||
"episode_number" => 142,
|
||||
"episode_type" => "standard",
|
||||
"id" => 1192242,
|
||||
"name" => "Matt Bomer, Zach Woods, Nick Griffin",
|
||||
"overview" => "",
|
||||
"production_code" => "",
|
||||
"runtime" => 45,
|
||||
"season_number" => 1,
|
||||
"show_id" => 63770,
|
||||
"still_path" => null,
|
||||
"vote_average" => 0.0,
|
||||
"vote_count" => 0,
|
||||
"crew" => [],
|
||||
"guest_stars" => [],
|
||||
"poster" => null,
|
||||
];
|
||||
}
|
||||
|
||||
private function getDownloadedEpisodes(): array
|
||||
{
|
||||
$episode1 = (object)[
|
||||
"season" => 10,
|
||||
"episode" => 142,
|
||||
"resolution" => "1080p",
|
||||
"codec" => "h264",
|
||||
"group" => "jebaited.mkv",
|
||||
"container" => "mkv",
|
||||
"title" => "42 stephen colbert 2025 07 21 sandra oh",
|
||||
"episodeName" => "E1 web",
|
||||
];
|
||||
|
||||
$episode2 = (object)[
|
||||
'season' => 10,
|
||||
'episode' => 142,
|
||||
'resolution' => '1080p',
|
||||
'codec' => 'x265',
|
||||
'group' => 'MeGusta[EZTVx.to].mkv',
|
||||
'container' => 'mkv',
|
||||
'title' => '42 Stephen Colbert 2025 07 21 Sandra Oh',
|
||||
'episodeName' => 'E1 HEVC'
|
||||
];
|
||||
|
||||
return [$episode1, $episode2];
|
||||
}
|
||||
}
|
||||
13
tests/bootstrap.php
Normal file
13
tests/bootstrap.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
if (method_exists(Dotenv::class, 'bootEnv')) {
|
||||
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
|
||||
}
|
||||
|
||||
if ($_SERVER['APP_DEBUG']) {
|
||||
umask(0000);
|
||||
}
|
||||
Reference in New Issue
Block a user