From f4337a23eb0720025c04ef614f724dae33754b32 Mon Sep 17 00:00:00 2001 From: DariusIII Date: Tue, 17 Mar 2026 12:48:23 +0100 Subject: [PATCH] Fix type error in books controller --- app/Http/Controllers/BooksController.php | 17 +++- tests/Feature/BooksControllerTest.php | 120 +++++++++++++++++++++++ 2 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 tests/Feature/BooksControllerTest.php diff --git a/app/Http/Controllers/BooksController.php b/app/Http/Controllers/BooksController.php index 726fd19de..ab99a1572 100644 --- a/app/Http/Controllers/BooksController.php +++ b/app/Http/Controllers/BooksController.php @@ -11,13 +11,19 @@ use Illuminate\Support\Arr; class BooksController extends BasePageController { + protected BookService $bookService; + + public function __construct(BookService $bookService) + { + parent::__construct(); + $this->bookService = $bookService; + } + /** * @throws \Exception */ public function index(Request $request, string $id = ''): mixed { - $bookService = new BookService; - $boocats = Category::getChildren(Category::BOOKS_ROOT); $btmp = []; @@ -40,13 +46,14 @@ class BooksController extends BasePageController $catarray = []; $catarray[] = $category; - $ordering = $bookService->getBookOrdering(); + $ordering = $this->bookService->getBookOrdering(); $orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : ''; $books = []; - $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'); - $rslt = $bookService->getBookRange($page, $catarray, $offset, (int) config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); + $rslt = $this->bookService->getBookRange($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()); $maxwords = 50; foreach ($results as $result) { diff --git a/tests/Feature/BooksControllerTest.php b/tests/Feature/BooksControllerTest.php new file mode 100644 index 000000000..caf585c2d --- /dev/null +++ b/tests/Feature/BooksControllerTest.php @@ -0,0 +1,120 @@ + '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_index_coerces_numeric_page_query_strings_to_ints_before_calling_book_service(): void + { + $bookService = Mockery::mock(BookService::class); + $bookService->shouldReceive('getBookOrdering') + ->once() + ->andReturn(['posted_desc']); + $bookService->shouldReceive('getBookRange') + ->once() + ->with(2, [Category::BOOKS_ROOT], 50, 50, '', []) + ->andReturn(collect()); + + $controller = new BooksController($bookService); + $user = new User; + $user->categoryexclusions = []; + $controller->userdata = $user; + + $request = Request::create('/Books', 'GET', ['page' => '2']); + + $response = $controller->index($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::BOOKS_ROOT, + 'title' => 'Books', + 'status' => 1, + 'disablepreview' => 0, + 'created_at' => now(), + 'updated_at' => now(), + ]); + + DB::table('categories')->insert([ + 'id' => Category::BOOKS_EBOOK, + 'title' => 'EBook', + 'parentid' => Category::BOOKS_ROOT, + 'status' => 1, + 'description' => 'Books', + 'disablepreview' => 0, + 'minsizetoformrelease' => 0, + 'maxsizetoformrelease' => 0, + 'root_categories_id' => Category::BOOKS_ROOT, + ]); + } +}