diff --git a/app/Http/Controllers/MusicController.php b/app/Http/Controllers/MusicController.php index c8dc43e6f..bd10690d7 100644 --- a/app/Http/Controllers/MusicController.php +++ b/app/Http/Controllers/MusicController.php @@ -13,14 +13,22 @@ use Illuminate\Support\Arr; class MusicController extends BasePageController { + protected MusicService $musicService; + + protected GenreService $genreService; + + public function __construct(MusicService $musicService, GenreService $genreService) + { + parent::__construct(); + $this->musicService = $musicService; + $this->genreService = $genreService; + } + /** * @throws \Exception */ public function show(Request $request, string $id = ''): mixed { - $music = new MusicService; - $gen = new GenreService; - $musiccats = Category::getChildren(Category::MUSIC_ROOT); $mtmp = []; foreach ($musiccats as $mcat) { @@ -43,20 +51,21 @@ class MusicController extends BasePageController $catarray = []; $catarray[] = $category; - $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1; + $pageInput = $request->input('page'); + $page = is_scalar($pageInput) && preg_match('/^\d+$/', (string) $pageInput) === 1 ? max(1, (int) $pageInput) : 1; $offset = ($page - 1) * (int) config('nntmux.items_per_cover_page'); - $ordering = $music->getMusicOrdering(); + $ordering = $this->musicService->getMusicOrdering(); $orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, true) ? $request->input('ob') : ''; $musics = []; - $rslt = $music->getMusicRange($page, $catarray, $offset, (int) config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); + $rslt = $this->musicService->getMusicRange($page, $catarray, $offset, (int) config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); $results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, (int) config('nntmux.items_per_cover_page'), $page, $request->url(), $request->query()); $artist = ($request->has('artist') && ! empty($request->input('artist'))) ? stripslashes($request->input('artist')) : ''; $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; - $genres = $gen->getGenres((string) GenreService::MUSIC_TYPE, true); + $genres = $this->genreService->getGenres((string) GenreService::MUSIC_TYPE, true); $tmpgnr = []; foreach ($genres as $gn) { /** @var Genre $gn */ diff --git a/tests/Feature/MusicControllerTest.php b/tests/Feature/MusicControllerTest.php new file mode 100644 index 000000000..68cf27bc8 --- /dev/null +++ b/tests/Feature/MusicControllerTest.php @@ -0,0 +1,128 @@ + 'sqlite', + 'database.connections.sqlite.database' => ':memory:', + 'app.key' => 'base64:'.base64_encode(random_bytes(32)), + 'nntmux.items_per_cover_page' => 50, + 'nntmux.cache_expiry_long' => 5, + ]); + + DB::purge(); + DB::reconnect(); + Cache::flush(); + + $this->createSchema(); + $this->seedCategories(); + } + + public function test_show_coerces_numeric_page_query_strings_to_ints_before_calling_music_service(): void + { + $musicService = Mockery::mock(MusicService::class); + $musicService->shouldReceive('getMusicOrdering') + ->once() + ->andReturn(['posted_desc']); + $musicService->shouldReceive('getMusicRange') + ->once() + ->with(2, [Category::MUSIC_ROOT], 50, 50, '', []) + ->andReturn(collect()); + + $genreService = Mockery::mock(GenreService::class); + $genreService->shouldReceive('getGenres') + ->once() + ->with((string) GenreService::MUSIC_TYPE, true) + ->andReturn(new EloquentCollection); + + $controller = new MusicController($musicService, $genreService); + $user = new User; + $user->categoryexclusions = []; + $controller->userdata = $user; + + $request = Request::create('/Audio', 'GET', ['page' => '2']); + + $response = $controller->show($request); + + $this->assertSame(2, $response->getData()['results']->currentPage()); + $this->assertInstanceOf(LengthAwarePaginator::class, $response->getData()['results']); + } + + private function createSchema(): void + { + Schema::create('settings', function (Blueprint $table): void { + $table->string('name')->primary(); + $table->text('value')->nullable(); + }); + + Schema::create('root_categories', function (Blueprint $table): void { + $table->unsignedInteger('id')->primary(); + $table->string('title'); + $table->integer('status')->default(1); + $table->boolean('disablepreview')->default(false); + $table->timestamps(); + }); + + Schema::create('categories', function (Blueprint $table): void { + $table->unsignedInteger('id')->primary(); + $table->string('title'); + $table->unsignedInteger('parentid')->nullable(); + $table->integer('status')->default(1); + $table->text('description')->nullable(); + $table->boolean('disablepreview')->default(false); + $table->unsignedBigInteger('minsizetoformrelease')->default(0); + $table->unsignedBigInteger('maxsizetoformrelease')->default(0); + $table->unsignedInteger('root_categories_id')->nullable(); + }); + } + + private function seedCategories(): void + { + DB::table('root_categories')->insert([ + 'id' => Category::MUSIC_ROOT, + 'title' => 'Music', + 'status' => 1, + 'disablepreview' => 0, + 'created_at' => now(), + 'updated_at' => now(), + ]); + + DB::table('categories')->insert([ + 'id' => Category::MUSIC_MP3, + 'title' => 'MP3', + 'parentid' => Category::MUSIC_ROOT, + 'status' => 1, + 'description' => 'Music', + 'disablepreview' => 0, + 'minsizetoformrelease' => 0, + 'maxsizetoformrelease' => 0, + 'root_categories_id' => Category::MUSIC_ROOT, + ]); + } +}