feat(test): add tests song visibility

This commit is contained in:
Phan An 2024-01-16 22:14:14 +01:00
parent 891cabaeb8
commit 71f5e1d804
9 changed files with 87 additions and 51 deletions

View file

@ -1,28 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ChangeSongsVisibilityRequest;
use App\Models\User;
use App\Repositories\SongRepository;
use App\Services\SongService;
use Illuminate\Contracts\Auth\Authenticatable;
class MakeSongsPrivateController extends Controller
{
/** @param User $user */
public function __invoke(
ChangeSongsVisibilityRequest $request,
SongRepository $repository,
SongService $songService,
Authenticatable $user
) {
$songs = $repository->getMany(ids: $request->songs, scopedUser: $user);
$songs->each(fn ($song) => $this->authorize('own', $song));
$songService->makeSongsPrivate($songs);
return response()->noContent();
}
}

View file

@ -6,23 +6,18 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\API\ChangeSongsVisibilityRequest; use App\Http\Requests\API\ChangeSongsVisibilityRequest;
use App\Models\Song; use App\Models\Song;
use App\Models\User; use App\Models\User;
use App\Repositories\SongRepository;
use App\Services\SongService; use App\Services\SongService;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
class MakeSongsPublicController extends Controller class PrivatizeSongsController extends Controller
{ {
/** @param User $user */ /** @param User $user */
public function __invoke( public function __invoke(ChangeSongsVisibilityRequest $request, SongService $songService, Authenticatable $user)
ChangeSongsVisibilityRequest $request, {
SongRepository $repository,
SongService $songService,
Authenticatable $user
) {
$songs = Song::query()->findMany($request->songs); $songs = Song::query()->findMany($request->songs);
$songs->each(fn ($song) => $this->authorize('own', $song)); $songs->each(fn ($song) => $this->authorize('own', $song));
$songService->makeSongsPublic($songs); $songService->privatizeSongs($songs);
return response()->noContent(); return response()->noContent();
} }

View file

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ChangeSongsVisibilityRequest;
use App\Models\Song;
use App\Models\User;
use App\Services\SongService;
use Illuminate\Contracts\Auth\Authenticatable;
class PublicizeSongsController extends Controller
{
/** @param User $user */
public function __invoke(ChangeSongsVisibilityRequest $request, SongService $songService, Authenticatable $user)
{
$songs = Song::query()->findMany($request->songs);
$songs->each(fn ($song) => $this->authorize('own', $song));
$songService->publicizeSongs($songs);
return response()->noContent();
}
}

View file

@ -82,12 +82,12 @@ class SongService
return $this->songRepository->getOne($song->id); return $this->songRepository->getOne($song->id);
} }
public function makeSongsPublic(Collection $songs): void public function publicizeSongs(Collection $songs): void
{ {
Song::query()->whereIn('id', $songs->pluck('id'))->update(['is_public' => true]); Song::query()->whereIn('id', $songs->pluck('id'))->update(['is_public' => true]);
} }
public function makeSongsPrivate(Collection $songs): void public function privatizeSongs(Collection $songs): void
{ {
Song::query()->whereIn('id', $songs->pluck('id'))->update(['is_public' => false]); Song::query()->whereIn('id', $songs->pluck('id'))->update(['is_public' => false]);
} }

View file

@ -243,7 +243,7 @@ export const songStore = {
}, },
async makePublic (songs: Song[]) { async makePublic (songs: Song[]) {
await http.put('songs/make-public', { await http.put('songs/publicize', {
songs: songs.map(song => song.id) songs: songs.map(song => song.id)
}) })
@ -251,7 +251,7 @@ export const songStore = {
}, },
async makePrivate (songs: Song[]) { async makePrivate (songs: Song[]) {
await http.put('songs/make-private', { await http.put('songs/privatize', {
songs: songs.map(song => song.id) songs: songs.map(song => song.id)
}) })

View file

@ -23,14 +23,14 @@ use App\Http\Controllers\API\FetchSongsForQueueController;
use App\Http\Controllers\API\GenreController; use App\Http\Controllers\API\GenreController;
use App\Http\Controllers\API\GenreSongController; use App\Http\Controllers\API\GenreSongController;
use App\Http\Controllers\API\LikeMultipleSongsController; use App\Http\Controllers\API\LikeMultipleSongsController;
use App\Http\Controllers\API\MakeSongsPrivateController;
use App\Http\Controllers\API\MakeSongsPublicController;
use App\Http\Controllers\API\ObjectStorage\S3\SongController as S3SongController; use App\Http\Controllers\API\ObjectStorage\S3\SongController as S3SongController;
use App\Http\Controllers\API\PlaylistController; use App\Http\Controllers\API\PlaylistController;
use App\Http\Controllers\API\PlaylistFolderController; use App\Http\Controllers\API\PlaylistFolderController;
use App\Http\Controllers\API\PlaylistFolderPlaylistController; use App\Http\Controllers\API\PlaylistFolderPlaylistController;
use App\Http\Controllers\API\PlaylistSongController; use App\Http\Controllers\API\PlaylistSongController;
use App\Http\Controllers\API\PrivatizeSongsController;
use App\Http\Controllers\API\ProfileController; use App\Http\Controllers\API\ProfileController;
use App\Http\Controllers\API\PublicizeSongsController;
use App\Http\Controllers\API\QueueStateController; use App\Http\Controllers\API\QueueStateController;
use App\Http\Controllers\API\RegisterPlayController; use App\Http\Controllers\API\RegisterPlayController;
use App\Http\Controllers\API\ScrobbleController; use App\Http\Controllers\API\ScrobbleController;
@ -160,8 +160,8 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::post('invitations', [UserInvitationController::class, 'invite']); Route::post('invitations', [UserInvitationController::class, 'invite']);
Route::delete('invitations', [UserInvitationController::class, 'revoke']); Route::delete('invitations', [UserInvitationController::class, 'revoke']);
Route::put('songs/make-public', MakeSongsPublicController::class); Route::put('songs/publicize', PublicizeSongsController::class);
Route::put('songs/make-private', MakeSongsPrivateController::class); Route::put('songs/privatize', PrivatizeSongsController::class);
Route::post('licenses/activate', ActivateLicenseController::class); Route::post('licenses/activate', ActivateLicenseController::class);
}); });

View file

@ -133,4 +133,49 @@ class SongTest extends TestCase
$this->deleteAs('api/songs', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser) $this->deleteAs('api/songs', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser)
->assertSuccessful(); ->assertSuccessful();
} }
public function testPublicizeSongs(): void
{
$user = create_user();
/** @var Song $songs */
$songs = Song::factory(3)->for($user, 'owner')->private()->create();
$this->putAs('api/songs/publicize', ['songs' => $songs->pluck('id')->toArray()], $user)
->assertSuccessful();
$songs->each(static function (Song $song): void {
$song->refresh();
self::assertTrue($song->is_public);
});
}
public function testPrivatizeSongs(): void
{
$user = create_user();
/** @var Song $songs */
$songs = Song::factory(3)->for($user, 'owner')->public()->create();
$this->putAs('api/songs/privatize', ['songs' => $songs->pluck('id')->toArray()], $user)
->assertSuccessful();
$songs->each(static function (Song $song): void {
$song->refresh();
self::assertFalse($song->is_public);
});
}
public function testPublicizingOrPrivatizingSongsRequiresOwnership(): void
{
$songs = Song::factory(3)->public()->create();
$this->putAs('api/songs/privatize', ['songs' => $songs->pluck('id')->toArray()])
->assertForbidden();
$otherSongs = Song::factory(3)->private()->create();
$this->putAs('api/songs/publicize', ['songs' => $otherSongs->pluck('id')->toArray()])
->assertForbidden();
}
} }

View file

@ -27,13 +27,13 @@ class SongVisibilityTest extends TestCase
$externalSongs = Song::factory(3)->for($anotherUser, 'owner')->private()->create(); $externalSongs = Song::factory(3)->for($anotherUser, 'owner')->private()->create();
// We can't make public songs that are not ours. // We can't make public songs that are not ours.
$this->putAs('api/songs/make-public', ['songs' => $externalSongs->pluck('id')->toArray()], $currentUser) $this->putAs('api/songs/publicize', ['songs' => $externalSongs->pluck('id')->toArray()], $currentUser)
->assertForbidden(); ->assertForbidden();
// But we can our own songs. // But we can our own songs.
$ownSongs = Song::factory(3)->for($currentUser, 'owner')->create(); $ownSongs = Song::factory(3)->for($currentUser, 'owner')->create();
$this->putAs('api/songs/make-public', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser) $this->putAs('api/songs/publicize', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser)
->assertSuccessful(); ->assertSuccessful();
$ownSongs->each(static fn (Song $song) => self::assertTrue($song->refresh()->is_public)); $ownSongs->each(static fn (Song $song) => self::assertTrue($song->refresh()->is_public));
@ -48,13 +48,13 @@ class SongVisibilityTest extends TestCase
$externalSongs = Song::factory(3)->for($anotherUser, 'owner')->public()->create(); $externalSongs = Song::factory(3)->for($anotherUser, 'owner')->public()->create();
// We can't make private songs that are not ours. // We can't make private songs that are not ours.
$this->putAs('api/songs/make-private', ['songs' => $externalSongs->pluck('id')->toArray()], $currentUser) $this->putAs('api/songs/privatize', ['songs' => $externalSongs->pluck('id')->toArray()], $currentUser)
->assertForbidden(); ->assertForbidden();
// But we can our own songs. // But we can our own songs.
$ownSongs = Song::factory(3)->for($currentUser, 'owner')->create(); $ownSongs = Song::factory(3)->for($currentUser, 'owner')->create();
$this->putAs('api/songs/make-private', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser) $this->putAs('api/songs/privatize', ['songs' => $ownSongs->pluck('id')->toArray()], $currentUser)
->assertSuccessful(); ->assertSuccessful();
$ownSongs->each(static fn (Song $song) => self::assertFalse($song->refresh()->is_public)); $ownSongs->each(static fn (Song $song) => self::assertFalse($song->refresh()->is_public));

View file

@ -14,10 +14,10 @@ class SongVisibilityTest extends TestCase
$owner = create_admin(); $owner = create_admin();
Song::factory(3)->create(); Song::factory(3)->create();
$this->putAs('api/songs/make-public', ['songs' => Song::query()->pluck('id')->all()], $owner) $this->putAs('api/songs/publicize', ['songs' => Song::query()->pluck('id')->all()], $owner)
->assertForbidden(); ->assertForbidden();
$this->putAs('api/songs/make-private', ['songs' => Song::query()->pluck('id')->all()], $owner) $this->putAs('api/songs/privatize', ['songs' => Song::query()->pluck('id')->all()], $owner)
->assertForbidden(); ->assertForbidden();
} }
} }