withoutMiddleware([ VerifyCsrfToken::class, \Illuminate\Session\Middleware\AuthenticateSession::class, ]); } // ─── Pagination partial: First + Last buttons ───── public function test_pagination_partial_renders_first_and_last_controls(): void { $paginator = new LengthAwarePaginator( items: ['a', 'b', 'c'], total: 100, perPage: 10, currentPage: 5, options: ['path' => '/videos'] ); $html = view('partials.pagination', [ 'paginator' => $paginator, 'elements' => $paginator->linkCollection()->toArray(), ])->render(); $this->assertStringContainsString('aria-label="First page"', $html); $this->assertStringContainsString('aria-label="Last page"', $html); $this->assertStringContainsString('aria-label="Previous page"', $html); $this->assertStringContainsString('aria-label="Next page"', $html); // The anchors should link to page 1 and page 10 respectively. $this->assertStringContainsString('href="/videos?page=1"', $html); $this->assertStringContainsString('href="/videos?page=10"', $html); } public function test_pagination_disables_first_on_page_one(): void { // Two-page paginator — if there's only one page the partial // short-circuits via @if($paginator->hasPages()) and renders // nothing, which isn't what we're testing. $paginator = new LengthAwarePaginator( items: ['a'], total: 20, perPage: 10, currentPage: 1, options: ['path' => '/videos'] ); $html = view('partials.pagination', [ 'paginator' => $paginator, 'elements' => $paginator->linkCollection()->toArray(), ])->render(); // On page 1 the First button is a disabled span, not an anchor. $this->assertMatchesRegularExpression( '/]+class="pag-item disabled"[^>]+title="First page"/', $html ); } // ─── Admin videos list: HTML-stripped description ─ public function test_admin_video_description_renders_without_html_tags(): void { $owner = User::factory()->create([ 'username' => 'u'.substr(bin2hex(random_bytes(4)), 0, 8), 'role' => 'super_admin', ]); $video = Video::create([ 'user_id' => $owner->id, 'title' => 'The Full Video Title That Will Be Ellipsized', 'description' => '

Hello world link

', 'filename' => 'users/x/videos/y/video.mp4', 'path' => 'users/x/videos/y/video.mp4', 'type' => 'generic', 'visibility' => 'public', 'status' => 'ready', 'share_token' => bin2hex(random_bytes(8)), ]); $this->actingAs($owner); $html = $this->get('/admin/videos')->getContent(); // Admin list must render plain text, not literal

/ . $this->assertStringNotContainsString('<p>Hello', $html, 'Description must be stripped of HTML tags before display.'); $this->assertStringContainsString('Hello world link', $html, 'Stripped text should still be visible.'); // Title tooltip in both the title column and description preview. $this->assertStringContainsString( 'title="The Full Video Title That Will Be Ellipsized"', $html, 'Admin title column must carry a title="" attribute for the full name.' ); } // ─── Dashboard: Ready label ────────────────────── public function test_dashboard_ready_stat_card_uses_the_new_label(): void { $owner = User::factory()->create([ 'username' => 'ad'.substr(bin2hex(random_bytes(4)), 0, 6), 'role' => 'super_admin', ]); $this->actingAs($owner); $html = $this->get('/admin/dashboard')->getContent(); $this->assertStringContainsString('>Ready<', $html); $this->assertStringNotContainsString('>Live Videos<', $html, 'The old "Live Videos" stat-card label should be gone.'); } }