mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat(test|api): add PlaylistSong tests
This commit is contained in:
parent
b3ee1ff528
commit
334c53727e
34 changed files with 224 additions and 95 deletions
|
@ -43,6 +43,8 @@ class PlaylistSongController extends Controller
|
|||
abort_if($playlist->is_smart, Response::HTTP_FORBIDDEN);
|
||||
|
||||
$this->playlistService->addSongsToPlaylist($playlist, $request->songs);
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
public function remove(Playlist $playlist, RemoveSongsFromPlaylistRequest $request)
|
||||
|
@ -52,5 +54,7 @@ class PlaylistSongController extends Controller
|
|||
abort_if($playlist->is_smart, Response::HTTP_FORBIDDEN);
|
||||
|
||||
$this->playlistService->removeSongsFromPlaylist($playlist, $request->songs);
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ class Playlist extends Model
|
|||
protected $guarded = ['id'];
|
||||
|
||||
protected $casts = [
|
||||
'user_id' => 'int',
|
||||
'rules' => SmartPlaylistRulesCast::class,
|
||||
];
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ class User extends Authenticatable
|
|||
protected $appends = ['avatar'];
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'int',
|
||||
'is_admin' => 'bool',
|
||||
'preferences' => UserPreferencesCast::class,
|
||||
];
|
||||
|
|
|
@ -9,6 +9,6 @@ class PlaylistPolicy
|
|||
{
|
||||
public function owner(User $user, Playlist $playlist): bool
|
||||
{
|
||||
return $user->id === $playlist->user_id;
|
||||
return $playlist->user->is($user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ class UserPolicy
|
|||
|
||||
public function destroy(User $currentUser, User $userToDestroy): bool
|
||||
{
|
||||
return $currentUser->is_admin && $currentUser->id !== $userToDestroy->id;
|
||||
return $currentUser->is_admin && $currentUser->isNot($userToDestroy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,30 +8,28 @@ use Throwable;
|
|||
|
||||
final class SmartPlaylistRuleGroup implements Arrayable
|
||||
{
|
||||
public ?int $id;
|
||||
|
||||
/** @var Collection|array<SmartPlaylistRule> */
|
||||
public Collection $rules;
|
||||
private function __construct(public ?int $id, public Collection $rules)
|
||||
{
|
||||
}
|
||||
|
||||
public static function tryCreate(array $jsonArray): ?self
|
||||
{
|
||||
try {
|
||||
return self::create($jsonArray);
|
||||
} catch (Throwable $exception) {
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function create(array $jsonArray): self
|
||||
{
|
||||
$group = new self();
|
||||
$group->id = $jsonArray['id'] ?? null;
|
||||
$id = $jsonArray['id'] ?? null;
|
||||
|
||||
$group->rules = collect(array_map(static function (array $rawRuleConfig) {
|
||||
$rules = collect(array_map(static function (array $rawRuleConfig) {
|
||||
return SmartPlaylistRule::create($rawRuleConfig);
|
||||
}, $jsonArray['rules']));
|
||||
|
||||
return $group;
|
||||
return new self($id, $rules);
|
||||
}
|
||||
|
||||
/** @return array<mixed> */
|
||||
|
|
|
@ -33,7 +33,7 @@ class AlbumCoverTest extends TestCase
|
|||
return $album->id === 9999;
|
||||
}), 'Foo', 'jpeg');
|
||||
|
||||
$response = $this->putAsUser('api/album/' . $album->id . '/cover', [
|
||||
$response = $this->putAs('api/album/' . $album->id . '/cover', [
|
||||
'cover' => 'data:image/jpeg;base64,Rm9v',
|
||||
], User::factory()->admin()->create());
|
||||
|
||||
|
@ -49,7 +49,7 @@ class AlbumCoverTest extends TestCase
|
|||
->shouldReceive('writeAlbumCover')
|
||||
->never();
|
||||
|
||||
$this->putAsUser('api/album/' . $album->id . '/cover', [
|
||||
$this->putAs('api/album/' . $album->id . '/cover', [
|
||||
'cover' => 'data:image/jpeg;base64,Rm9v',
|
||||
], User::factory()->create())
|
||||
->assertStatus(403);
|
||||
|
|
|
@ -37,7 +37,7 @@ class AlbumThumbnailTest extends TestCase
|
|||
}))
|
||||
->andReturn($thumbnailUrl);
|
||||
|
||||
$response = $this->getAsUser("api/album/{$createdAlbum->id}/thumbnail");
|
||||
$response = $this->getAs("api/album/{$createdAlbum->id}/thumbnail");
|
||||
$response->assertJson(['thumbnailUrl' => $thumbnailUrl]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class ArtistImageTest extends TestCase
|
|||
return $artist->id === 9999;
|
||||
}), 'Foo', 'jpeg');
|
||||
|
||||
$this->putAsUser('api/artist/9999/image', [
|
||||
$this->putAs('api/artist/9999/image', [
|
||||
'image' => 'data:image/jpeg;base64,Rm9v',
|
||||
], User::factory()->admin()->create())
|
||||
->assertStatus(200);
|
||||
|
@ -47,7 +47,7 @@ class ArtistImageTest extends TestCase
|
|||
->shouldReceive('writeArtistImage')
|
||||
->never();
|
||||
|
||||
$this->putAsUser('api/artist/9999/image', [
|
||||
$this->putAs('api/artist/9999/image', [
|
||||
'image' => 'data:image/jpeg;base64,Rm9v',
|
||||
], User::factory()->create())
|
||||
->assertStatus(403);
|
||||
|
|
|
@ -164,9 +164,7 @@ class DownloadTest extends TestCase
|
|||
self::mock(InteractionRepository::class)
|
||||
->shouldReceive('getUserFavorites')
|
||||
->once()
|
||||
->with(Mockery::on(static function (User $retrievedUser) use ($user): bool {
|
||||
return $retrievedUser->id === $user->id;
|
||||
}))
|
||||
->with(Mockery::on(static fn (User $retrievedUser) => $retrievedUser->is($user)))
|
||||
->andReturn($favorites);
|
||||
|
||||
$this->downloadService
|
||||
|
|
|
@ -26,7 +26,7 @@ class InteractionTest extends TestCase
|
|||
|
||||
/** @var Song $song */
|
||||
$song = Song::orderBy('id')->first();
|
||||
$this->postAsUser('api/interaction/play', ['song' => $song->id], $user);
|
||||
$this->postAs('api/interaction/play', ['song' => $song->id], $user);
|
||||
|
||||
self::assertDatabaseHas('interactions', [
|
||||
'user_id' => $user->id,
|
||||
|
@ -35,7 +35,7 @@ class InteractionTest extends TestCase
|
|||
]);
|
||||
|
||||
// Try again
|
||||
$this->postAsUser('api/interaction/play', ['song' => $song->id], $user);
|
||||
$this->postAs('api/interaction/play', ['song' => $song->id], $user);
|
||||
|
||||
self::assertDatabaseHas('interactions', [
|
||||
'user_id' => $user->id,
|
||||
|
@ -53,7 +53,7 @@ class InteractionTest extends TestCase
|
|||
|
||||
/** @var Song $song */
|
||||
$song = Song::orderBy('id')->first();
|
||||
$this->postAsUser('api/interaction/like', ['song' => $song->id], $user);
|
||||
$this->postAs('api/interaction/like', ['song' => $song->id], $user);
|
||||
|
||||
self::assertDatabaseHas('interactions', [
|
||||
'user_id' => $user->id,
|
||||
|
@ -62,7 +62,7 @@ class InteractionTest extends TestCase
|
|||
]);
|
||||
|
||||
// Try again
|
||||
$this->postAsUser('api/interaction/like', ['song' => $song->id], $user);
|
||||
$this->postAs('api/interaction/like', ['song' => $song->id], $user);
|
||||
|
||||
self::assertDatabaseHas('interactions', [
|
||||
'user_id' => $user->id,
|
||||
|
@ -82,7 +82,7 @@ class InteractionTest extends TestCase
|
|||
$songs = Song::orderBy('id')->take(2)->get();
|
||||
$songIds = array_pluck($songs->toArray(), 'id');
|
||||
|
||||
$this->postAsUser('api/interaction/batch/like', ['songs' => $songIds], $user);
|
||||
$this->postAs('api/interaction/batch/like', ['songs' => $songIds], $user);
|
||||
|
||||
foreach ($songs as $song) {
|
||||
self::assertDatabaseHas('interactions', [
|
||||
|
@ -92,7 +92,7 @@ class InteractionTest extends TestCase
|
|||
]);
|
||||
}
|
||||
|
||||
$this->postAsUser('api/interaction/batch/unlike', ['songs' => $songIds], $user);
|
||||
$this->postAs('api/interaction/batch/unlike', ['songs' => $songIds], $user);
|
||||
|
||||
foreach ($songs as $song) {
|
||||
self::assertDatabaseHas('interactions', [
|
||||
|
|
|
@ -31,7 +31,7 @@ class LastfmTest extends TestCase
|
|||
{
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
$this->postAsUser('api/lastfm/session-key', ['key' => 'foo'], $user)
|
||||
$this->postAs('api/lastfm/session-key', ['key' => 'foo'], $user)
|
||||
->assertStatus(204);
|
||||
|
||||
self::assertEquals('foo', $user->refresh()->lastfm_session_key);
|
||||
|
@ -120,7 +120,7 @@ class LastfmTest extends TestCase
|
|||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
self::assertNotNull($user->lastfm_session_key);
|
||||
$this->deleteAsUser('api/lastfm/disconnect', [], $user);
|
||||
$this->deleteAs('api/lastfm/disconnect', [], $user);
|
||||
$user->refresh();
|
||||
|
||||
self::assertNull($user->lastfm_session_key);
|
||||
|
|
|
@ -33,9 +33,7 @@ class PlaylistSongTest extends TestCase
|
|||
$user = User::factory()->create();
|
||||
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
$playlist = Playlist::factory()->create([], $user);
|
||||
|
||||
/** @var array<Song>|Collection $songs */
|
||||
$songs = Song::orderBy('id')->take(4)->get();
|
||||
|
@ -46,7 +44,7 @@ class PlaylistSongTest extends TestCase
|
|||
|
||||
$path = $useDeprecatedRoute ? "api/playlist/$playlist->id/sync" : "api/playlist/$playlist->id/songs";
|
||||
|
||||
$this->putAsUser($path, [
|
||||
$this->putAs($path, [
|
||||
'songs' => $songs->pluck('id')->all(),
|
||||
], $user)->assertOk();
|
||||
|
||||
|
@ -77,7 +75,7 @@ class PlaylistSongTest extends TestCase
|
|||
$songs = Song::factory(2)->create();
|
||||
$playlist->songs()->saveMany($songs);
|
||||
|
||||
$this->getAsUser("api/playlist/$playlist->id/songs", $user)
|
||||
$this->getAs("api/playlist/$playlist->id/songs", $user)
|
||||
->assertJson($songs->pluck('id')->all());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class PlaylistTest extends TestCase
|
|||
/** @var array<Song>|Collection $songs */
|
||||
$songs = Song::orderBy('id')->take(3)->get();
|
||||
|
||||
$response = $this->postAsUser('api/playlist', [
|
||||
$response = $this->postAs('api/playlist', [
|
||||
'name' => 'Foo Bar',
|
||||
'songs' => $songs->pluck('id')->toArray(),
|
||||
'rules' => [],
|
||||
|
@ -52,7 +52,7 @@ class PlaylistTest extends TestCase
|
|||
'value' => ['Bob Dylan'],
|
||||
]);
|
||||
|
||||
$this->postAsUser('api/playlist', [
|
||||
$this->postAs('api/playlist', [
|
||||
'name' => 'Smart Foo Bar',
|
||||
'rules' => [
|
||||
[
|
||||
|
@ -74,7 +74,7 @@ class PlaylistTest extends TestCase
|
|||
|
||||
public function testCreatingSmartPlaylistIgnoresSongs(): void
|
||||
{
|
||||
$this->postAsUser('api/playlist', [
|
||||
$this->postAs('api/playlist', [
|
||||
'name' => 'Smart Foo Bar',
|
||||
'rules' => [
|
||||
[
|
||||
|
@ -100,7 +100,7 @@ class PlaylistTest extends TestCase
|
|||
|
||||
public function testCreatingPlaylistWithNonExistentSongsFails(): void
|
||||
{
|
||||
$response = $this->postAsUser('api/playlist', [
|
||||
$response = $this->postAs('api/playlist', [
|
||||
'name' => 'Foo Bar',
|
||||
'rules' => [],
|
||||
'songs' => ['foo'],
|
||||
|
@ -120,7 +120,7 @@ class PlaylistTest extends TestCase
|
|||
'name' => 'Foo',
|
||||
]);
|
||||
|
||||
$this->putAsUser("api/playlist/$playlist->id", ['name' => 'Bar'], $user);
|
||||
$this->putAs("api/playlist/$playlist->id", ['name' => 'Bar'], $user);
|
||||
|
||||
self::assertSame('Bar', $playlist->refresh()->name);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ class PlaylistTest extends TestCase
|
|||
'name' => 'Foo',
|
||||
]);
|
||||
|
||||
$response = $this->putAsUser("api/playlist/$playlist->id", ['name' => 'Qux']);
|
||||
$response = $this->putAs("api/playlist/$playlist->id", ['name' => 'Qux']);
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ class PlaylistTest extends TestCase
|
|||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->deleteAsUser("api/playlist/$playlist->id", [], $user);
|
||||
$this->deleteAs("api/playlist/$playlist->id", [], $user);
|
||||
self::assertDatabaseMissing('playlists', ['id' => $playlist->id]);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ class PlaylistTest extends TestCase
|
|||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create();
|
||||
|
||||
$this->deleteAsUser("api/playlist/$playlist->id")
|
||||
$this->deleteAs("api/playlist/$playlist->id")
|
||||
->assertStatus(403);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class ProfileTest extends TestCase
|
|||
|
||||
public function testUpdateProfileRequiresCurrentPassword(): void
|
||||
{
|
||||
$this->putAsUser('api/me', [
|
||||
$this->putAs('api/me', [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
], $this->user)
|
||||
|
@ -28,7 +28,7 @@ class ProfileTest extends TestCase
|
|||
|
||||
public function testUpdateProfileWithoutNewPassword(): void
|
||||
{
|
||||
$this->putAsUser('api/me', [
|
||||
$this->putAs('api/me', [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
'current_password' => 'secret',
|
||||
|
@ -43,7 +43,7 @@ class ProfileTest extends TestCase
|
|||
|
||||
public function testUpdateProfileWithNewPassword(): void
|
||||
{
|
||||
$this->putAsUser('api/me', [
|
||||
$this->putAs('api/me', [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
'new_password' => 'new-secret',
|
||||
|
|
|
@ -25,7 +25,7 @@ class ScrobbleTest extends TestCase
|
|||
->with($song->album->artist->name, $song->title, $timestamp, $song->album->name, $user->lastfm_session_key)
|
||||
->once();
|
||||
|
||||
$this->postAsUser("/api/$song->id/scrobble", ['timestamp' => $timestamp], $user)
|
||||
$this->postAs("/api/$song->id/scrobble", ['timestamp' => $timestamp], $user)
|
||||
->assertNoContent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class SettingTest extends TestCase
|
|||
{
|
||||
$this->mediaSyncService->shouldReceive('sync')->once();
|
||||
|
||||
$this->putAsUser('/api/settings', ['media_path' => __DIR__], User::factory()->admin()->create())
|
||||
$this->putAs('/api/settings', ['media_path' => __DIR__], User::factory()->admin()->create())
|
||||
->assertSuccessful();
|
||||
|
||||
self::assertEquals(__DIR__, Setting::get('media_path'));
|
||||
|
@ -31,7 +31,7 @@ class SettingTest extends TestCase
|
|||
|
||||
public function testNonAdminCannotSaveSettings(): void
|
||||
{
|
||||
$this->putAsUser('/api/settings', ['media_path' => __DIR__], User::factory()->create())
|
||||
$this->putAs('/api/settings', ['media_path' => __DIR__], User::factory()->create())
|
||||
->assertForbidden();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class SongTest extends TestCase
|
|||
{
|
||||
$song = Song::first();
|
||||
|
||||
$this->putAsUser('/api/songs', [
|
||||
$this->putAs('/api/songs', [
|
||||
'songs' => [$song->id],
|
||||
'data' => [
|
||||
'title' => 'Foo Bar',
|
||||
|
@ -56,7 +56,7 @@ class SongTest extends TestCase
|
|||
$song = Song::first();
|
||||
$originalArtistId = $song->artist->id;
|
||||
|
||||
$this->putAsUser('/api/songs', [
|
||||
$this->putAs('/api/songs', [
|
||||
'songs' => [$song->id],
|
||||
'data' => [
|
||||
'title' => '',
|
||||
|
@ -79,7 +79,7 @@ class SongTest extends TestCase
|
|||
{
|
||||
$songIds = Song::latest()->take(3)->pluck('id')->toArray();
|
||||
|
||||
$this->putAsUser('/api/songs', [
|
||||
$this->putAs('/api/songs', [
|
||||
'songs' => $songIds,
|
||||
'data' => [
|
||||
'title' => 'foo',
|
||||
|
@ -109,7 +109,7 @@ class SongTest extends TestCase
|
|||
$originalSongs = Song::latest()->take(3)->get();
|
||||
$songIds = $originalSongs->pluck('id')->toArray();
|
||||
|
||||
$this->putAsUser('/api/songs', [
|
||||
$this->putAs('/api/songs', [
|
||||
'songs' => $songIds,
|
||||
'data' => [
|
||||
'title' => 'Foo Bar',
|
||||
|
@ -143,7 +143,7 @@ class SongTest extends TestCase
|
|||
{
|
||||
$song = Song::first();
|
||||
|
||||
$this->putAsUser('/api/songs', [
|
||||
$this->putAs('/api/songs', [
|
||||
'songs' => [$song->id],
|
||||
'data' => [
|
||||
'title' => 'Foo Bar',
|
||||
|
|
|
@ -8,7 +8,7 @@ use Tests\TestCase as BaseTestCase;
|
|||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
private function jsonAsUser(?User $user, string $method, $uri, array $data = [], array $headers = []): TestResponse
|
||||
private function jsonAs(?User $user, string $method, $uri, array $data = [], array $headers = []): TestResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $user ?: User::factory()->create();
|
||||
|
@ -17,23 +17,23 @@ abstract class TestCase extends BaseTestCase
|
|||
return parent::json($method, $uri, $data, $headers);
|
||||
}
|
||||
|
||||
protected function getAsUser(string $url, ?User $user = null): TestResponse
|
||||
protected function getAs(string $url, ?User $user = null): TestResponse
|
||||
{
|
||||
return $this->jsonAsUser($user, 'get', $url);
|
||||
return $this->jsonAs($user, 'get', $url);
|
||||
}
|
||||
|
||||
protected function deleteAsUser(string $url, array $data = [], ?User $user = null): TestResponse
|
||||
protected function deleteAs(string $url, array $data = [], ?User $user = null): TestResponse
|
||||
{
|
||||
return $this->jsonAsUser($user, 'delete', $url, $data);
|
||||
return $this->jsonAs($user, 'delete', $url, $data);
|
||||
}
|
||||
|
||||
protected function postAsUser(string $url, array $data, ?User $user = null): TestResponse
|
||||
protected function postAs(string $url, array $data, ?User $user = null): TestResponse
|
||||
{
|
||||
return $this->jsonAsUser($user, 'post', $url, $data);
|
||||
return $this->jsonAs($user, 'post', $url, $data);
|
||||
}
|
||||
|
||||
protected function putAsUser(string $url, array $data, ?User $user = null): TestResponse
|
||||
protected function putAs(string $url, array $data, ?User $user = null): TestResponse
|
||||
{
|
||||
return $this->jsonAsUser($user, 'put', $url, $data);
|
||||
return $this->jsonAs($user, 'put', $url, $data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class UploadTest extends TestCase
|
|||
->shouldReceive('handleUploadedFile')
|
||||
->never();
|
||||
|
||||
$this->postAsUser('/api/upload', ['file' => $file], User::factory()->create())->assertStatus(403);
|
||||
$this->postAs('/api/upload', ['file' => $file], User::factory()->create())->assertStatus(403);
|
||||
}
|
||||
|
||||
/** @return array<mixed> */
|
||||
|
@ -55,7 +55,7 @@ class UploadTest extends TestCase
|
|||
->with($file)
|
||||
->andThrow($exceptionClass);
|
||||
|
||||
$this->postAsUser('/api/upload', ['file' => $file], User::factory()->admin()->create())
|
||||
$this->postAs('/api/upload', ['file' => $file], User::factory()->admin()->create())
|
||||
->assertStatus($statusCode);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class UploadTest extends TestCase
|
|||
->with($file)
|
||||
->andReturn($song);
|
||||
|
||||
$this->postAsUser('/api/upload', ['file' => $file], User::factory()->admin()->create())
|
||||
$this->postAs('/api/upload', ['file' => $file], User::factory()->admin()->create())
|
||||
->assertJsonStructure([
|
||||
'song',
|
||||
'album',
|
||||
|
|
|
@ -14,7 +14,7 @@ class UserTest extends TestCase
|
|||
|
||||
public function testNonAdminCannotCreateUser(): void
|
||||
{
|
||||
$this->postAsUser('api/user', [
|
||||
$this->postAs('api/user', [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
'password' => 'secret',
|
||||
|
@ -24,7 +24,7 @@ class UserTest extends TestCase
|
|||
|
||||
public function testAdminCreatesUser(): void
|
||||
{
|
||||
$this->postAsUser('api/user', [
|
||||
$this->postAs('api/user', [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
'password' => 'secret',
|
||||
|
@ -46,7 +46,7 @@ class UserTest extends TestCase
|
|||
/** @var User $user */
|
||||
$user = User::factory()->admin()->create(['password' => 'secret']);
|
||||
|
||||
$this->putAsUser("api/user/$user->id", [
|
||||
$this->putAs("api/user/$user->id", [
|
||||
'name' => 'Foo',
|
||||
'email' => 'bar@baz.com',
|
||||
'password' => 'new-secret',
|
||||
|
@ -67,7 +67,7 @@ class UserTest extends TestCase
|
|||
$user = User::factory()->create();
|
||||
$admin = User::factory()->admin()->create();
|
||||
|
||||
$this->deleteAsUser("api/user/$user->id", [], $admin);
|
||||
$this->deleteAs("api/user/$user->id", [], $admin);
|
||||
self::assertDatabaseMissing('users', ['id' => $user->id]);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class UserTest extends TestCase
|
|||
$admin = User::factory()->admin()->create();
|
||||
|
||||
// A user can't delete himself
|
||||
$this->deleteAsUser("api/user/$admin->id", [], $admin)
|
||||
$this->deleteAs("api/user/$admin->id", [], $admin)
|
||||
->assertStatus(403);
|
||||
|
||||
self::assertDatabaseHas('users', ['id' => $admin->id]);
|
||||
|
|
|
@ -57,7 +57,7 @@ class AlbumInformationTest extends TestCase
|
|||
]
|
||||
));
|
||||
|
||||
$this->getAsUser('api/albums/' . $album->id . '/information')
|
||||
$this->getAs('api/albums/' . $album->id . '/information')
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ class AlbumInformationTest extends TestCase
|
|||
/** @var Album $album */
|
||||
$album = Album::factory()->create();
|
||||
|
||||
$this->getAsUser('api/albums/' . $album->id . '/information')
|
||||
$this->getAs('api/albums/' . $album->id . '/information')
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ class AlbumSongTest extends TestCase
|
|||
/** @var Album $album */
|
||||
$album = Album::factory()->create();
|
||||
|
||||
Song::factory(5)->create([
|
||||
'album_id' => $album->id,
|
||||
]);
|
||||
Song::factory(5)->for($album)->create();
|
||||
|
||||
$this->getAsUser('api/albums/' . $album->id . '/songs')
|
||||
$this->getAs('api/albums/' . $album->id . '/songs')
|
||||
->assertJsonStructure(['*' => SongTest::JSON_STRUCTURE]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class AlbumTest extends TestCase
|
|||
{
|
||||
Album::factory(10)->create();
|
||||
|
||||
$this->getAsUser('api/albums')
|
||||
$this->getAs('api/albums')
|
||||
->assertJsonStructure(self::JSON_COLLECTION_STRUCTURE);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ class AlbumTest extends TestCase
|
|||
/** @var Album $album */
|
||||
$album = Album::factory()->create();
|
||||
|
||||
$this->getAsUser('api/albums/' . $album->id)
|
||||
$this->getAs('api/albums/' . $album->id)
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class ArtistInformationTest extends TestCase
|
|||
],
|
||||
));
|
||||
|
||||
$this->getAsUser('api/artists/' . $artist->id . '/information')
|
||||
$this->getAs('api/artists/' . $artist->id . '/information')
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ArtistInformationTest extends TestCase
|
|||
/** @var Artist $artist */
|
||||
$artist = Artist::factory()->create();
|
||||
|
||||
$this->getAsUser('api/artists/' . $artist->id . '/information')
|
||||
$this->getAs('api/artists/' . $artist->id . '/information')
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ class ArtistSongTest extends TestCase
|
|||
/** @var Artist $artist */
|
||||
$artist = Artist::factory()->create();
|
||||
|
||||
Song::factory(5)->create([
|
||||
'artist_id' => $artist->id,
|
||||
]);
|
||||
Song::factory(5)->for($artist)->create();
|
||||
|
||||
$this->getAsUser('api/artists/' . $artist->id . '/songs')
|
||||
$this->getAs('api/artists/' . $artist->id . '/songs')
|
||||
->assertJsonStructure(['*' => SongTest::JSON_STRUCTURE]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class ArtistTest extends TestCase
|
|||
{
|
||||
Artist::factory(10)->create();
|
||||
|
||||
$this->getAsUser('api/artists')
|
||||
$this->getAs('api/artists')
|
||||
->assertJsonStructure(self::JSON_COLLECTION_STRUCTURE);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ArtistTest extends TestCase
|
|||
/** @var Artist $artist */
|
||||
$artist = Artist::factory()->create();
|
||||
|
||||
$this->getAsUser('api/artists/' . $artist->id)
|
||||
$this->getAs('api/artists/' . $artist->id)
|
||||
->assertJsonStructure(self::JSON_STRUCTURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ class DataTest extends TestCase
|
|||
{
|
||||
public function testIndex(): void
|
||||
{
|
||||
$this->getAsUser('/api/data')->assertJsonStructure([
|
||||
$this->getAs('/api/data')->assertJsonStructure([
|
||||
'settings',
|
||||
'playlists',
|
||||
'current_user',
|
||||
|
|
|
@ -19,7 +19,7 @@ class ExcerptSearchTest extends TestCase
|
|||
Album::factory()->create(['name' => 'Foo Number Five']);
|
||||
Album::factory(4)->create();
|
||||
|
||||
$this->getAsUser('api/search?q=foo')
|
||||
$this->getAs('api/search?q=foo')
|
||||
->assertJsonStructure([
|
||||
'songs' => ['*' => SongTest::JSON_STRUCTURE],
|
||||
'artists' => ['*' => ArtistTest::JSON_STRUCTURE],
|
||||
|
|
|
@ -16,7 +16,7 @@ class FavoriteTest extends TestCase
|
|||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->getAsUser('api/favorites', $user)
|
||||
$this->getAs('api/favorites', $user)
|
||||
->assertJsonStructure(['*' => SongTest::JSON_STRUCTURE]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ class OverviewTest extends TestCase
|
|||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
|
||||
Interaction::factory(20)->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
Interaction::factory(20)->for($user)->create();
|
||||
|
||||
$this->getAsUser('api/overview', $user)
|
||||
$this->getAs('api/overview', $user)
|
||||
->assertJsonStructure([
|
||||
'most_played_songs' => ['*' => SongTest::JSON_STRUCTURE],
|
||||
'recently_played_songs' => ['*' => SongTest::JSON_STRUCTURE],
|
||||
|
|
|
@ -13,7 +13,7 @@ class PlayCountTest extends TestCase
|
|||
'play_count' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->postAsUser('/api/interaction/play', [
|
||||
$response = $this->postAs('/api/interaction/play', [
|
||||
'song' => $interaction->song->id,
|
||||
], $interaction->user);
|
||||
|
||||
|
|
139
tests/Feature/V6/PlaylistSongTest.php
Normal file
139
tests/Feature/V6/PlaylistSongTest.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\V6;
|
||||
|
||||
use App\Models\Playlist;
|
||||
use App\Models\Song;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class PlaylistSongTest extends TestCase
|
||||
{
|
||||
public function testGetNormalPlaylist(): void
|
||||
{
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create();
|
||||
$playlist->songs()->attach(Song::factory(5)->create());
|
||||
|
||||
$this->getAs('api/playlists/' . $playlist->id . '/songs', $playlist->user)
|
||||
->assertJsonStructure(['*' => SongTest::JSON_STRUCTURE]);
|
||||
}
|
||||
|
||||
public function testGetSmartPlaylist(): void
|
||||
{
|
||||
Song::factory()->create(['title' => 'A foo song']);
|
||||
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create([
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1658843809274,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1658843809274,
|
||||
'model' => 'title',
|
||||
'operator' => 'contains',
|
||||
'value' => ['foo'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->getAs('api/playlists/' . $playlist->id . '/songs', $playlist->user)
|
||||
->assertJsonStructure(['*' => SongTest::JSON_STRUCTURE]);
|
||||
}
|
||||
|
||||
public function testNonOwnerCannotAccessPlaylist(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->for($user)->create();
|
||||
$playlist->songs()->attach(Song::factory(5)->create());
|
||||
|
||||
$this->getAs('api/playlists/' . $playlist->id . '/songs')
|
||||
->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
public function testAddSongsToPlaylist(): void
|
||||
{
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create();
|
||||
|
||||
$songs = Song::factory(2)->create();
|
||||
|
||||
$this->postAs('api/playlists/' . $playlist->id . '/songs', [
|
||||
'songs' => $songs->map(static fn (Song $song) => $song->id)->all(),
|
||||
], $playlist->user)
|
||||
->assertNoContent();
|
||||
|
||||
self::assertEqualsCanonicalizing($songs->pluck('id')->all(), $playlist->songs->pluck('id')->all());
|
||||
}
|
||||
|
||||
public function testRemoveSongsFromPlaylist(): void
|
||||
{
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create();
|
||||
|
||||
$toRemainSongs = Song::factory(5)->create();
|
||||
$toBeRemovedSongs = Song::factory(2)->create();
|
||||
$playlist->songs()->attach($toRemainSongs->merge($toBeRemovedSongs));
|
||||
|
||||
self::assertCount(7, $playlist->songs);
|
||||
|
||||
$this->deleteAs('api/playlists/' . $playlist->id . '/songs', [
|
||||
'songs' => $toBeRemovedSongs->map(static fn (Song $song) => $song->id)->all(),
|
||||
], $playlist->user)
|
||||
->assertNoContent();
|
||||
|
||||
$playlist->refresh();
|
||||
|
||||
self::assertEqualsCanonicalizing($toRemainSongs->pluck('id')->all(), $playlist->songs->pluck('id')->all());
|
||||
}
|
||||
|
||||
public function testNonOwnerCannotModifyPlaylist(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->for($user)->create();
|
||||
|
||||
/** @var Song $song */
|
||||
$song = Song::factory()->create();
|
||||
|
||||
$this->postAs('api/playlists/' . $playlist->id . '/songs', ['songs' => [$song->id]])
|
||||
->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
|
||||
$this->deleteAs('api/playlists/' . $playlist->id . '/songs', ['songs' => [$song->id]])
|
||||
->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
public function testSmartPlaylistContentCannotBeModified(): void
|
||||
{
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()->create([
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1658843809274,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1658843809274,
|
||||
'model' => 'title',
|
||||
'operator' => 'contains',
|
||||
'value' => ['foo'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$songs = Song::factory(2)->create()->map(static fn (Song $song) => $song->id)->all();
|
||||
|
||||
$this->postAs('api/playlists/' . $playlist->id . '/songs', ['songs' => $songs], $playlist->user)
|
||||
->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
|
||||
$this->deleteAs('api/playlists/' . $playlist->id . '/songs', ['songs' => $songs], $playlist->user)
|
||||
->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ class YouTubeTest extends TestCase
|
|||
}), 'foo')
|
||||
->once();
|
||||
|
||||
$this->getAsUser("/api/youtube/search/song/{$song->id}?pageToken=foo")
|
||||
$this->getAs("/api/youtube/search/song/{$song->id}?pageToken=foo")
|
||||
->assertOk();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue