Files
takeone-youtube-clone/tests/Feature/Phase5ShortsTest.php
T
ghassanandClaude Opus 4.7 8812aaf336 test(phase-5): shorts deep-link, home shelf, branded 404
Five tests:
- /shorts/{id} renders the vertical feed with data-id matching the
  target short and includes the scrollIntoView bootstrap.
- /shorts/{id} 404s when the id resolves to a non-short video.
- Home page shows .home-shorts-shelf when at least one short exists,
  with a link to /shorts/{id} for every shelf card.
- Home page omits the shelf entirely when no shorts exist.
- An unknown URL returns 404 with the branded view, not the bare
  framework stacktrace.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-10-21 10:33:58 +03:00

142 lines
4.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Http\Middleware\VerifyCsrfToken;
use App\Models\User;
use App\Models\Video;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* Phase 5 — Shorts.
*
* Guards against regressions in the deep-link route, the Home shelf, and
* the branded 404 fallback.
*/
class Phase5ShortsTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
putenv('DB_CONNECTION=sqlite');
putenv('DB_DATABASE=:memory:');
$_ENV['DB_CONNECTION'] = 'sqlite';
$_ENV['DB_DATABASE'] = ':memory:';
parent::setUp();
$this->withoutMiddleware([
VerifyCsrfToken::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
]);
}
// ─── /shorts/{id} deep-link ──────────────────────
public function test_shorts_deep_link_renders_feed_scrolled_to_target(): void
{
$owner = $this->makeUser();
$short = $this->makeShort($owner, 'DEEP LINK SHORT');
$html = $this->get(route('videos.shorts.focused', $short))->assertOk()->getContent();
$this->assertStringContainsString('DEEP LINK SHORT', $html);
// The in-page scroller is driven by data-id matching the start id.
$this->assertStringContainsString('data-id="' . $short->id . '"', $html);
$this->assertStringContainsString('scrollIntoView', $html);
}
public function test_shorts_deep_link_404s_on_non_short(): void
{
$owner = $this->makeUser();
$regular = Video::create([
'user_id' => $owner->id,
'title' => 'not a short',
'description'=> '',
'filename' => 'users/x/videos/y/video.mp4',
'path' => 'users/x/videos/y/video.mp4',
'type' => 'generic',
'visibility' => 'public',
'status' => 'ready',
'is_shorts' => false,
'share_token'=> bin2hex(random_bytes(8)),
]);
$this->get('/shorts/' . Video::encodeId($regular->id))->assertStatus(404);
}
// ─── Home shelf ──────────────────────────────────
public function test_home_shows_shorts_shelf_when_shorts_exist(): void
{
$owner = $this->makeUser();
$s = $this->makeShort($owner, 'SHELF SHORT');
$html = $this->get(route('home'))->assertOk()->getContent();
$this->assertStringContainsString('home-shorts-shelf', $html);
$this->assertStringContainsString('SHELF SHORT', $html);
$this->assertStringContainsString('/shorts/' . Video::encodeId($s->id), $html);
}
public function test_home_omits_shorts_shelf_when_no_shorts(): void
{
$owner = $this->makeUser();
// A regular video so the home feed renders, but no shorts.
Video::create([
'user_id' => $owner->id,
'title' => 'reg',
'description'=> '',
'filename' => 'users/x/videos/y/video.mp4',
'path' => 'users/x/videos/y/video.mp4',
'type' => 'generic',
'visibility' => 'public',
'status' => 'ready',
'is_shorts' => false,
'share_token'=> bin2hex(random_bytes(8)),
]);
$html = $this->get(route('home'))->assertOk()->getContent();
$this->assertStringNotContainsString('home-shorts-shelf', $html);
}
// ─── Branded 404 ─────────────────────────────────
public function test_unknown_url_renders_branded_404(): void
{
$r = $this->get('/no-such-page')->assertStatus(404);
$r->assertSee('Error 404', false);
}
// ─── Helpers ─────────────────────────────────────
private function makeUser(): User
{
return User::factory()->create([
'username' => 'u'.substr(bin2hex(random_bytes(4)), 0, 8),
]);
}
private function makeShort(User $u, string $title): Video
{
return Video::create([
'user_id' => $u->id,
'title' => $title,
'description'=> '',
'filename' => 'users/x/videos/'.substr(bin2hex(random_bytes(4)), 0, 8).'/video.mp4',
'path' => 'users/x/videos/'.substr(bin2hex(random_bytes(4)), 0, 8).'/video.mp4',
'type' => 'generic',
'visibility' => 'public',
'status' => 'ready',
'is_shorts' => true,
'duration' => 45,
'orientation'=> 'portrait',
'share_token'=> bin2hex(random_bytes(8)),
]);
}
}