test(phase-6): channel handle, preview mode, playlist meta
Also tightens stat/post-video rendering so "0" prints as "0" and not "0.0" (Number::abbreviate(0, precision: 1) stringifies as "0.0", which leaked into the About tab's Total Views card and post-video badges). Four tests covering: - /@username opens the matching channel. - /@invalid url (space) 404s. - Owner view shows id="postForm"; preview?preview=1 hides it. - Zero-view playlist doesn't render "bi-eye … 0.0"; "1 videos" never renders in place of "1 video". Fixed a Blade dupe-declaration fatal that only fired in feature tests (two requests in one PHP process would redeclare notifVal()). Guarded with function_exists. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
e939dd3a53
commit
1b2377f20f
2 files changed
+116
-4
No files matched your search
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Http\Middleware\VerifyCsrfToken;
|
||||
use App\Models\Playlist;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Phase 6 — Channel / Studio / Live.
|
||||
*
|
||||
* Covers the handle-alias route, the composer being hidden in preview mode,
|
||||
* and the pluralised playlist meta.
|
||||
*/
|
||||
class Phase6ChannelTest 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,
|
||||
]);
|
||||
}
|
||||
|
||||
// ─── /@handle alias ─────────────────────────────
|
||||
|
||||
public function test_at_handle_url_opens_the_matching_channel(): void
|
||||
{
|
||||
$user = User::factory()->create([
|
||||
'name' => 'Handle Test',
|
||||
'username' => 'handletest-'.substr(bin2hex(random_bytes(3)), 0, 6),
|
||||
]);
|
||||
|
||||
$r = $this->get('/@' . $user->username)->assertOk();
|
||||
|
||||
$r->assertSee('Handle Test', false);
|
||||
}
|
||||
|
||||
public function test_at_handle_rejects_invalid_characters(): void
|
||||
{
|
||||
// Space in the handle must not match the /@ route.
|
||||
$this->get('/@not valid')->assertStatus(404);
|
||||
}
|
||||
|
||||
// ─── Preview-as-visitor hides composer ──────────
|
||||
|
||||
public function test_preview_as_visitor_hides_the_wall_composer(): void
|
||||
{
|
||||
$user = User::factory()->create([
|
||||
'username' => 'preview-'.substr(bin2hex(random_bytes(3)), 0, 6),
|
||||
]);
|
||||
$this->actingAs($user);
|
||||
|
||||
// The composer form carries id="postForm" and action pointing at
|
||||
// posts.store — specific enough that we don't collide with the
|
||||
// "ch-composer-*" literals that appear in inline JS strings.
|
||||
$owner = $this->get('/channel/' . $user->username)->getContent();
|
||||
$this->assertStringContainsString('id="postForm"', $owner,
|
||||
'Owner should see the composer form in normal view.');
|
||||
|
||||
$preview = $this->get('/channel/' . $user->username . '?preview=1')->getContent();
|
||||
$this->assertStringNotContainsString('id="postForm"', $preview,
|
||||
'Preview-as-visitor must hide the composer form.');
|
||||
}
|
||||
|
||||
// ─── Playlist card: pluralise + hide stray "0.0" ──
|
||||
|
||||
public function test_playlist_card_pluralises_videos_and_hides_zero_views(): void
|
||||
{
|
||||
$owner = User::factory()->create([
|
||||
'username' => 'pl-'.substr(bin2hex(random_bytes(3)), 0, 6),
|
||||
]);
|
||||
$this->actingAs($owner);
|
||||
$pl = Playlist::create([
|
||||
'user_id' => $owner->id,
|
||||
'name' => 'Empty Playlist',
|
||||
'visibility' => 'public',
|
||||
'share_token'=> bin2hex(random_bytes(8)),
|
||||
]);
|
||||
|
||||
$html = $this->get('/channel/' . $owner->username)->getContent();
|
||||
|
||||
// The specific bug: the view-count row ends with
|
||||
// `<i class="bi bi-eye" aria-hidden="true"></i> 0.0`
|
||||
// for a zero-view playlist. The fix hides the whole row for zero
|
||||
// views, so the "bi-eye ...0.0" sequence should never appear.
|
||||
$this->assertDoesNotMatchRegularExpression(
|
||||
'/bi-eye[^<]{0,200}0\.0/',
|
||||
$html,
|
||||
'Playlist meta must not emit "bi-eye … 0.0" for zero-view playlists.'
|
||||
);
|
||||
|
||||
// Plural must switch to singular for 1 video. Never "1 videos".
|
||||
$this->assertDoesNotMatchRegularExpression('/\b1 videos\b/i', $html);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user