262 lines
8.8 KiB
PHP
262 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Livewire;
|
|
|
|
use App\Livewire\PlaylistOverview;
|
|
use App\Models\Episode;
|
|
use App\Models\Gallery;
|
|
use App\Models\Hentai;
|
|
use App\Models\Playlist;
|
|
use App\Models\PlaylistEpisode;
|
|
use App\Models\Studios;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Foundation\Testing\RefreshDatabaseState;
|
|
use Livewire\Livewire;
|
|
use Tests\TestCase;
|
|
|
|
class PlaylistOverviewTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
/**
|
|
* The repo's post-launch data-fix migrations (e.g. 2026_01_08_213625)
|
|
* assume a populated production schema and fail on a fresh database, so
|
|
* the "testing" database is provisioned from a production schema dump
|
|
* instead of running migrate:fresh.
|
|
*/
|
|
protected function migrateDatabases(): void
|
|
{
|
|
RefreshDatabaseState::$migrated = true;
|
|
}
|
|
|
|
private function makePlaylist(int $episodeCount = 1): array
|
|
{
|
|
$user = User::factory()->create();
|
|
$playlist = Playlist::factory()->create(['user_id' => $user->id]);
|
|
$hentai = Hentai::factory()->create();
|
|
$studio = Studios::factory()->create();
|
|
|
|
for ($i = 1; $i <= $episodeCount; $i++) {
|
|
$episode = Episode::factory()->create([
|
|
'hentai_id' => $hentai->id,
|
|
'studios_id' => $studio->id,
|
|
'title' => sprintf('Episode %02d', $i),
|
|
]);
|
|
|
|
Gallery::factory()->create([
|
|
'hentai_id' => $hentai->id,
|
|
'episode_id' => $episode->id,
|
|
]);
|
|
|
|
PlaylistEpisode::factory()->create([
|
|
'playlist_id' => $playlist->id,
|
|
'episode_id' => $episode->id,
|
|
'position' => $i,
|
|
]);
|
|
}
|
|
|
|
return [$user, $playlist];
|
|
}
|
|
|
|
public function test_episodes_are_paginated(): void
|
|
{
|
|
[, $playlist] = $this->makePlaylist(30);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->assertViewHas('episodes', fn ($episodes) => $episodes->total() === 30
|
|
&& $episodes->count() === 25
|
|
&& $episodes->hasPages())
|
|
->assertSee('Episode 01')
|
|
->assertSee('Episode 25')
|
|
->assertDontSee('Episode 26');
|
|
}
|
|
|
|
public function test_per_page_selector_changes_page_size(): void
|
|
{
|
|
[, $playlist] = $this->makePlaylist(30);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->set('perPage', 100)
|
|
->assertViewHas('episodes', fn ($episodes) => $episodes->total() === 30
|
|
&& $episodes->count() === 30
|
|
&& ! $episodes->hasPages())
|
|
->assertSee('Episode 30');
|
|
}
|
|
|
|
public function test_per_page_is_restricted_to_allowed_values(): void
|
|
{
|
|
[, $playlist] = $this->makePlaylist(30);
|
|
|
|
Livewire::withQueryParams(['perPage' => 999])
|
|
->test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->assertSet('perPage', 25)
|
|
->assertViewHas('episodes', fn ($episodes) => $episodes->perPage() === 25);
|
|
}
|
|
|
|
public function test_search_filters_episodes_and_resets_page(): void
|
|
{
|
|
[, $playlist] = $this->makePlaylist(30);
|
|
|
|
$hentai = Hentai::factory()->create();
|
|
$studio = Studios::factory()->create();
|
|
$uniqueEpisode = Episode::factory()->create([
|
|
'hentai_id' => $hentai->id,
|
|
'studios_id' => $studio->id,
|
|
'title' => 'ZebraUnicornSearch',
|
|
]);
|
|
|
|
Gallery::factory()->create([
|
|
'hentai_id' => $hentai->id,
|
|
'episode_id' => $uniqueEpisode->id,
|
|
]);
|
|
|
|
PlaylistEpisode::factory()->create([
|
|
'playlist_id' => $playlist->id,
|
|
'episode_id' => $uniqueEpisode->id,
|
|
'position' => 31,
|
|
]);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('gotoPage', 2)
|
|
->assertSet('paginators.page', 2)
|
|
->set('search', 'ZebraUnicornSearch')
|
|
->assertSet('paginators.page', 1)
|
|
->assertSee('ZebraUnicornSearch')
|
|
->assertDontSee('Episode 02');
|
|
}
|
|
|
|
public function test_guest_sees_no_owner_controls(): void
|
|
{
|
|
[, $playlist] = $this->makePlaylist(3);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->assertDontSee('wire:click="moveUp')
|
|
->assertDontSee('wire:click="moveDown')
|
|
->assertDontSee('wire:click="remove');
|
|
}
|
|
|
|
public function test_only_owner_can_move_episodes(): void
|
|
{
|
|
[$user, $playlist] = $this->makePlaylist(3);
|
|
$otherUser = User::factory()->create();
|
|
|
|
$this->actingAs($otherUser);
|
|
|
|
$second = PlaylistEpisode::where('playlist_id', $playlist->id)->where('position', 2)->first();
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('moveUp', $second->id);
|
|
|
|
$this->assertSame(2, PlaylistEpisode::find($second->id)->position);
|
|
$this->assertSame(
|
|
[1, 2, 3],
|
|
PlaylistEpisode::where('playlist_id', $playlist->id)->orderBy('position')->pluck('position')->all()
|
|
);
|
|
}
|
|
|
|
public function test_owner_can_move_episode_up_and_down(): void
|
|
{
|
|
[$user, $playlist] = $this->makePlaylist(3);
|
|
|
|
$this->actingAs($user);
|
|
|
|
$second = PlaylistEpisode::where('playlist_id', $playlist->id)->where('position', 2)->first();
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('moveUp', $second->id)
|
|
->assertOk();
|
|
|
|
$this->assertSame(1, PlaylistEpisode::find($second->id)->position);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('moveDown', $second->id)
|
|
->assertOk();
|
|
|
|
$this->assertSame(2, PlaylistEpisode::find($second->id)->position);
|
|
$this->assertSame(
|
|
[1, 2, 3],
|
|
PlaylistEpisode::where('playlist_id', $playlist->id)->orderBy('position')->pluck('position')->all()
|
|
);
|
|
}
|
|
|
|
public function test_owner_can_remove_episode_and_positions_reorder(): void
|
|
{
|
|
[$user, $playlist] = $this->makePlaylist(5);
|
|
|
|
$this->actingAs($user);
|
|
|
|
$second = PlaylistEpisode::where('playlist_id', $playlist->id)->where('position', 2)->first();
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('remove', $second->id)
|
|
->assertOk();
|
|
|
|
$this->assertDatabaseMissing('playlist_episodes', ['id' => $second->id]);
|
|
$this->assertSame(
|
|
[1, 2, 3, 4],
|
|
PlaylistEpisode::where('playlist_id', $playlist->id)->orderBy('position')->pluck('position')->all()
|
|
);
|
|
}
|
|
|
|
public function test_removing_last_item_on_last_page_clamps_page(): void
|
|
{
|
|
[$user, $playlist] = $this->makePlaylist(26);
|
|
|
|
$this->actingAs($user);
|
|
|
|
$last = PlaylistEpisode::where('playlist_id', $playlist->id)->where('position', 26)->first();
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('gotoPage', 2)
|
|
->assertSet('paginators.page', 2)
|
|
->call('remove', $last->id)
|
|
->assertSet('paginators.page', 1)
|
|
->assertViewHas('episodes', fn ($episodes) => $episodes->total() === 25 && ! $episodes->hasPages());
|
|
}
|
|
|
|
public function test_edit_name_and_toggle_visibility_still_work(): void
|
|
{
|
|
[$user, $playlist] = $this->makePlaylist(2);
|
|
|
|
$this->actingAs($user);
|
|
|
|
Livewire::test(PlaylistOverview::class, ['playlist_id' => $playlist->id])
|
|
->call('editName')
|
|
->set('editingPlaylistName', 'Renamed Playlist')
|
|
->call('updateName')
|
|
->call('toggleVisibility')
|
|
->assertOk();
|
|
|
|
$this->assertDatabaseHas('playlists', [
|
|
'id' => $playlist->id,
|
|
'name' => 'Renamed Playlist',
|
|
'is_private' => false,
|
|
]);
|
|
}
|
|
|
|
public function test_public_playlist_page_renders(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$playlist = Playlist::factory()->create(['user_id' => $user->id, 'is_private' => false]);
|
|
|
|
$this->get('/playlist/'.$playlist->id)->assertOk();
|
|
|
|
$private = Playlist::factory()->create(['user_id' => $user->id, 'is_private' => true]);
|
|
|
|
$this->get('/playlist/'.$private->id)->assertNotFound();
|
|
}
|
|
|
|
public function test_user_playlist_page_renders(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$playlist = Playlist::factory()->create(['user_id' => $user->id, 'is_private' => true]);
|
|
|
|
$this->actingAs($user)->get('/user/playlist/'.$playlist->id)->assertOk();
|
|
|
|
$otherUser = User::factory()->create();
|
|
|
|
$this->actingAs($otherUser)->get('/user/playlist/'.$playlist->id)->assertNotFound();
|
|
}
|
|
}
|