user = User::factory()->create(); $this->withoutVite(); }); test('songs index page renders for authenticated users', function () { $response = $this->actingAs($this->user) ->get('/songs'); $response->assertOk(); $response->assertInertia(fn ($page) => $page->component('Songs/Index')); }); test('songs index page redirects unauthenticated users to login', function () { $response = $this->get('/songs'); $response->assertRedirect('/login'); }); test('songs index route is named songs.index', function () { $this->actingAs($this->user); $url = route('songs.index'); expect($url)->toContain('/songs'); }); test('songs api returns data for songs page', function () { Song::factory()->count(3)->create(); $response = $this->actingAs($this->user) ->getJson('/api/songs'); $response->assertOk() ->assertJsonStructure([ 'data' => [['id', 'title', 'ccli_id', 'has_translation', 'created_at', 'updated_at']], 'meta' => ['current_page', 'last_page', 'per_page', 'total'], ]); expect($response->json('meta.total'))->toBe(3); }); test('songs api search filters by title', function () { Song::factory()->create(['title' => 'Großer Gott wir loben dich']); Song::factory()->create(['title' => 'Amazing Grace']); $response = $this->actingAs($this->user) ->getJson('/api/songs?search=Großer'); $response->assertOk(); expect($response->json('meta.total'))->toBe(1); expect($response->json('data.0.title'))->toBe('Großer Gott wir loben dich'); }); test('songs api search filters by ccli id', function () { Song::factory()->create(['ccli_id' => '7654321', 'title' => 'Song A']); Song::factory()->create(['ccli_id' => '1234567', 'title' => 'Song B']); $response = $this->actingAs($this->user) ->getJson('/api/songs?search=7654321'); $response->assertOk(); expect($response->json('meta.total'))->toBe(1); expect($response->json('data.0.ccli_id'))->toBe('7654321'); }); test('songs api does not return soft-deleted songs', function () { Song::factory()->count(2)->create(); Song::factory()->create(['deleted_at' => now()]); $response = $this->actingAs($this->user) ->getJson('/api/songs'); $response->assertOk(); expect($response->json('meta.total'))->toBe(2); }); test('songs api paginates results', function () { Song::factory()->count(25)->create(); $response = $this->actingAs($this->user) ->getJson('/api/songs?per_page=10'); $response->assertOk(); expect($response->json('meta.total'))->toBe(25); expect($response->json('meta.per_page'))->toBe(10); expect($response->json('meta.last_page'))->toBe(3); expect(count($response->json('data')))->toBe(10); }); test('songs api delete soft-deletes a song', function () { $song = Song::factory()->create(['title' => 'To Delete']); $response = $this->actingAs($this->user) ->deleteJson("/api/songs/{$song->id}"); $response->assertOk(); expect(Song::find($song->id))->toBeNull(); expect(Song::withTrashed()->find($song->id))->not->toBeNull(); });