feat(plus): add upload tests

This commit is contained in:
Phan An 2024-01-11 13:41:33 +01:00
parent 7861478f12
commit dd7c1e754a
59 changed files with 310 additions and 378 deletions

View file

@ -71,10 +71,3 @@ function attempt_unless($condition, callable $callback, bool $log = true): mixed
{
return !value($condition) ? attempt($callback, $log) : null;
}
if (!function_exists('test_path')) {
function test_path(string $path = ''): string
{
return base_path('tests' . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR));
}
}

View file

@ -57,17 +57,22 @@
],
"psr-4": {
"App\\": "app/",
"Tests\\": "tests/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
"app/Helpers.php"
"app/helpers.php"
]
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php"
],
"psr-4": {
"Tests\\": "tests/",
"Database\\Factories\\": "database/factories/"
},
"files": [
"tests/helpers.php"
]
},
"scripts": {

View file

@ -4,12 +4,14 @@ namespace Tests\Feature;
use App\Events\LibraryChanged;
use App\Models\Album;
use App\Models\User;
use App\Services\MediaMetadataService;
use Mockery;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_admin;
use function Tests\create_user;
class AlbumCoverTest extends TestCase
{
private MediaMetadataService|MockInterface $mediaMetadataService;
@ -25,9 +27,6 @@ class AlbumCoverTest extends TestCase
{
$this->expectsEvents(LibraryChanged::class);
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var Album $album */
$album = Album::factory()->create();
@ -36,7 +35,7 @@ class AlbumCoverTest extends TestCase
->once()
->with(Mockery::on(static fn (Album $target) => $target->is($album)), 'Foo', 'jpeg');
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], $user)
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], create_admin())
->assertOk();
}
@ -49,10 +48,7 @@ class AlbumCoverTest extends TestCase
->shouldReceive('writeAlbumCover')
->never();
/** @var User $user */
$user = User::factory()->create();
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], $user)
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], create_user())
->assertForbidden();
}
}

View file

@ -4,12 +4,13 @@ namespace Tests\Feature;
use App\Events\LibraryChanged;
use App\Models\Artist;
use App\Models\User;
use App\Services\MediaMetadataService;
use Mockery;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_admin;
class ArtistImageTest extends TestCase
{
private MediaMetadataService|MockInterface $mediaMetadataService;
@ -25,9 +26,6 @@ class ArtistImageTest extends TestCase
{
$this->expectsEvents(LibraryChanged::class);
/** @var User $admin */
$admin = User::factory()->admin()->create();
Artist::factory()->create(['id' => 9999]);
$this->mediaMetadataService
@ -35,7 +33,7 @@ class ArtistImageTest extends TestCase
->once()
->with(Mockery::on(static fn (Artist $artist) => $artist->id === 9999), 'Foo', 'jpeg');
$this->putAs('api/artist/9999/image', ['image' => 'data:image/jpeg;base64,Rm9v'], $admin)
$this->putAs('api/artist/9999/image', ['image' => 'data:image/jpeg;base64,Rm9v'], create_admin())
->assertOk();
}

View file

@ -2,15 +2,16 @@
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
use function Tests\create_user;
class AuthTest extends TestCase
{
public function testLogIn(): void
{
User::factory()->create([
create_user([
'email' => 'koel@koel.dev',
'password' => Hash::make('secret'),
]);
@ -34,8 +35,7 @@ class AuthTest extends TestCase
public function testLogOut(): void
{
/** @var User $user */
$user = User::factory()->create([
$user = create_user([
'email' => 'koel@koel.dev',
'password' => Hash::make('secret'),
]);

View file

@ -7,13 +7,15 @@ use App\Models\Artist;
use App\Models\Interaction;
use App\Models\Playlist;
use App\Models\Song;
use App\Models\User;
use App\Services\DownloadService;
use Illuminate\Support\Collection;
use Mockery;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class DownloadTest extends TestCase
{
private MockInterface|DownloadService $downloadService;
@ -42,9 +44,7 @@ class DownloadTest extends TestCase
{
/** @var Song $song */
$song = Song::factory()->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->downloadService
->shouldReceive('getDownloadablePath')
@ -60,11 +60,9 @@ class DownloadTest extends TestCase
public function testDownloadMultipleSongs(): void
{
/** @var User $user */
$user = User::factory()->create();
/** @var array<Song>|Collection $songs */
$songs = Song::factory(2)->create();
$user = create_user();
$this->downloadService
->shouldReceive('getDownloadablePath')
@ -87,11 +85,8 @@ class DownloadTest extends TestCase
{
/** @var Album $album */
$album = Album::factory()->create();
$songs = Song::factory(3)->for($album)->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->downloadService
->shouldReceive('getDownloadablePath')
@ -111,11 +106,8 @@ class DownloadTest extends TestCase
{
/** @var Artist $artist */
$artist = Artist::factory()->create();
$songs = Song::factory(3)->for($artist)->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->downloadService
->shouldReceive('getDownloadablePath')
@ -133,9 +125,7 @@ class DownloadTest extends TestCase
public function testDownloadPlaylist(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$songs = Song::factory(3)->create();
/** @var Playlist $playlist */
@ -161,9 +151,7 @@ class DownloadTest extends TestCase
{
/** @var Playlist $playlist */
$playlist = Playlist::factory()->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->get("download/playlist/{$playlist->id}?api_token=" . $user->createToken('Koel')->plainTextToken)
->assertForbidden();
@ -171,9 +159,7 @@ class DownloadTest extends TestCase
public function testDownloadFavorites(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$favorites = Interaction::factory(3)->for($user)->create(['liked' => true]);
$this->downloadService

View file

@ -3,16 +3,15 @@
namespace Tests\Feature;
use App\Models\Interaction;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_user;
class FavoriteSongTest extends TestCase
{
public function testIndex(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
Interaction::factory(5)->for($user)->create(['liked' => true]);
$this->getAs('api/songs/favorite', $user)

View file

@ -4,7 +4,7 @@ namespace Tests\Feature;
use Tests\TestCase;
class DataTest extends TestCase
class InitialDataTest extends TestCase
{
public function testIndex(): void
{

View file

@ -6,18 +6,18 @@ use App\Events\MultipleSongsLiked;
use App\Events\SongLikeToggled;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class InteractionTest extends TestCase
{
public function testIncreasePlayCount(): void
{
$this->withoutEvents();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $song */
$song = Song::factory()->create();
@ -43,8 +43,7 @@ class InteractionTest extends TestCase
{
$this->expectsEvents(SongLikeToggled::class);
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $song */
$song = Song::factory()->create();
@ -70,8 +69,7 @@ class InteractionTest extends TestCase
{
$this->expectsEvents(MultipleSongsLiked::class);
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Collection|array<Song> $songs */
$songs = Song::factory(2)->create();

View file

@ -4,10 +4,12 @@ namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Song;
use App\Models\User;
use App\Services\DownloadService;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class DownloadTest extends TestCase
{
public function setUp(): void
@ -19,8 +21,7 @@ class DownloadTest extends TestCase
public function testDownloadPolicy(): void
{
/** @var User $owner */
$owner = User::factory()->create();
$owner = create_user();
$apiToken = $owner->createToken('Koel')->plainTextToken;
// Can't download a private song that doesn't belong to the user

View file

@ -4,10 +4,11 @@ namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class InteractionTest extends TestCase
{
public function setUp(): void
@ -21,8 +22,7 @@ class InteractionTest extends TestCase
{
$this->withoutEvents();
/** @var User $owner */
$owner = User::factory()->create();
$owner = create_user();
// Can't increase play count of a private song that doesn't belong to the user
/** @var Song $externalPrivateSong */
@ -47,8 +47,7 @@ class InteractionTest extends TestCase
{
$this->withoutEvents();
/** @var User $owner */
$owner = User::factory()->create();
$owner = create_user();
// Can't like a private song that doesn't belong to the user
/** @var Song $externalPrivateSong */
@ -73,8 +72,7 @@ class InteractionTest extends TestCase
{
$this->withoutEvents();
/** @var User $owner */
$owner = User::factory()->create();
$owner = create_user();
// Can't batch like private songs that don't belong to the user
/** @var Collection $externalPrivateSongs */
@ -104,8 +102,7 @@ class InteractionTest extends TestCase
{
$this->withoutEvents();
/** @var User $owner */
$owner = User::factory()->create();
$owner = create_user();
// Can't batch unlike private songs that don't belong to the user
/** @var Collection $externalPrivateSongs */

View file

@ -4,13 +4,15 @@ namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Song;
use App\Models\User;
use App\Services\Streamers\DirectStreamerInterface;
use App\Services\TokenManager;
use App\Values\CompositeToken;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class SongPlayTest extends TestCase
{
public function setUp(): void
@ -22,11 +24,8 @@ class SongPlayTest extends TestCase
public function testPlayPublicUnownedSong(): void
{
/** @var User $user */
$user = User::factory()->create();
/** @var CompositeToken $token */
$token = app(TokenManager::class)->createCompositeToken($user);
$token = app(TokenManager::class)->createCompositeToken(create_user());
/** @var Song $song */
$song = Song::factory()->public()->create([
@ -55,7 +54,6 @@ class SongPlayTest extends TestCase
/** @var CompositeToken $token */
$token = app(TokenManager::class)->createCompositeToken($song->owner);
$mockStreamer = $this->mock(DirectStreamerInterface::class);
$mockStreamer->shouldReceive('setSong')->with(
@ -75,11 +73,8 @@ class SongPlayTest extends TestCase
'path' => test_path('songs/blank.mp3'),
]);
/** @var User $owner */
$owner = User::factory()->create();
/** @var CompositeToken $token */
$token = app(TokenManager::class)->createCompositeToken($owner);
$token = app(TokenManager::class)->createCompositeToken(create_user());
$this->get("play/$song->id?t=$token->audioToken")
->assertForbidden();

View file

@ -4,10 +4,11 @@ namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class SongTest extends TestCase
{
public function setUp(): void
@ -19,8 +20,7 @@ class SongTest extends TestCase
public function testShowSongPolicy(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $publicSong */
$publicSong = Song::factory()->public()->create();
@ -43,11 +43,8 @@ class SongTest extends TestCase
public function testEditSongsPolicy(): void
{
/** @var User $currentUser */
$currentUser = User::factory()->create();
/** @var User $anotherUser */
$anotherUser = User::factory()->create();
$currentUser = create_user();
$anotherUser = create_user();
/** @var Collection<Song> $externalUnownedSongs */
$externalUnownedSongs = Song::factory(3)->for($anotherUser, 'owner')->private()->create();
@ -83,11 +80,8 @@ class SongTest extends TestCase
public function testDeleteSongsPolicy(): void
{
/** @var User $currentUser */
$currentUser = User::factory()->create();
/** @var User $anotherUser */
$anotherUser = User::factory()->create();
$currentUser = create_user();
$anotherUser = create_user();
/** @var Collection<Song> $externalUnownedSongs */
$externalUnownedSongs = Song::factory(3)->for($anotherUser, 'owner')->private()->create();

View file

@ -4,10 +4,11 @@ namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class SongVisibilityTest extends TestCase
{
public function setUp(): void
@ -19,11 +20,8 @@ class SongVisibilityTest extends TestCase
public function testMakingSongPublic(): void
{
/** @var User $currentUser */
$currentUser = User::factory()->create();
/** @var User $anotherUser */
$anotherUser = User::factory()->create();
$currentUser = create_user();
$anotherUser = create_user();
/** @var Collection<Song> $externalSongs */
$externalSongs = Song::factory(3)->for($anotherUser, 'owner')->private()->create();
@ -43,11 +41,8 @@ class SongVisibilityTest extends TestCase
public function testMakingSongPrivate(): void
{
/** @var User $currentUser */
$currentUser = User::factory()->create();
/** @var User $anotherUser */
$anotherUser = User::factory()->create();
$currentUser = create_user();
$anotherUser = create_user();
/** @var Collection<Song> $externalSongs */
$externalSongs = Song::factory(3)->for($anotherUser, 'owner')->public()->create();

View file

@ -0,0 +1,39 @@
<?php
namespace Tests\Feature\KoelPlus;
use App\Facades\License;
use App\Models\Setting;
use App\Models\Song;
use Illuminate\Http\UploadedFile;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class UploadTest extends TestCase
{
private UploadedFile $file;
public function setUp(): void
{
parent::setUp();
License::fakePlusLicense();
Setting::set('media_path', public_path('sandbox/media'));
$this->file = UploadedFile::fromFile(test_path('songs/full.mp3'), 'song.mp3'); //@phpstan-ignore-line
}
public function testUploads(): void
{
$user = create_user();
$this->postAs('api/upload', ['file' => $this->file], $user)->assertSuccessful();
self::assertDirectoryExists(public_path("sandbox/media/__KOEL_UPLOADS_\${$user->id}__"));
/** @var Song $song */
$song = Song::query()->latest()->first();
self::assertSame($song->owner_id, $user->id);
self::assertFalse($song->is_public);
}
}

View file

@ -2,7 +2,6 @@
namespace Tests\Feature;
use App\Models\User;
use App\Services\LastfmService;
use App\Services\TokenManager;
use Laravel\Sanctum\NewAccessToken;
@ -11,12 +10,13 @@ use Mockery;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_user;
class LastfmTest extends TestCase
{
public function testSetSessionKey(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->postAs('api/lastfm/session-key', ['key' => 'foo'], $user)
->assertNoContent();
@ -25,8 +25,7 @@ class LastfmTest extends TestCase
public function testConnectToLastfm(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$token = $user->createToken('Koel')->plainTextToken;
/** @var NewAccessToken|MockInterface $temporaryToken */
@ -52,8 +51,7 @@ class LastfmTest extends TestCase
public function testCallback(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$token = $user->createToken('Koel')->plainTextToken;
self::assertNotNull(PersonalAccessToken::findToken($token));
@ -77,8 +75,7 @@ class LastfmTest extends TestCase
public function testRetrieveAndStoreSessionKey(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$lastfm = Mockery::mock(LastfmService::class)->makePartial();
@ -103,12 +100,12 @@ class LastfmTest extends TestCase
public function testDisconnectUser(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
self::assertNotNull($user->lastfm_session_key);
$this->deleteAs('api/lastfm/disconnect', [], $user);
$user->refresh();
$this->deleteAs('api/lastfm/disconnect', [], $user);
$user->refresh();
self::assertNull($user->lastfm_session_key);
}
}

View file

@ -3,15 +3,15 @@
namespace Tests\Feature;
use App\Models\Interaction;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_user;
class OverviewTest extends TestCase
{
public function testIndex(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
Interaction::factory(20)->for($user)->create();

View file

@ -5,10 +5,11 @@ namespace Tests\Feature;
use App\Events\PlaybackStarted;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
use function Tests\create_user;
class PlayCountTest extends TestCase
{
public function testStoreExistingEntry(): void
@ -40,8 +41,7 @@ class PlayCountTest extends TestCase
/** @var Song $song */
$song = Song::factory()->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->postAs('/api/interaction/play', ['song' => $song->id], $user)
->assertJsonStructure([

View file

@ -3,9 +3,10 @@
namespace Tests\Feature;
use App\Models\PlaylistFolder;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_user;
class PlaylistFolderTest extends TestCase
{
private const JSON_STRUCTURE = [
@ -18,8 +19,7 @@ class PlaylistFolderTest extends TestCase
public function testListing(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
PlaylistFolder::factory()->for($user)->count(3)->create();
$this->getAs('api/playlist-folders', $user)
@ -29,8 +29,7 @@ class PlaylistFolderTest extends TestCase
public function testCreate(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->postAs('api/playlist-folders', ['name' => 'Classical'], $user)
->assertJsonStructure(self::JSON_STRUCTURE);

View file

@ -4,10 +4,11 @@ namespace Tests\Feature;
use App\Models\Playlist;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class PlaylistSongTest extends TestCase
{
public function testGetNormalPlaylist(): void
@ -47,10 +48,8 @@ class PlaylistSongTest extends TestCase
public function testNonOwnerCannotAccessPlaylist(): void
{
$user = User::factory()->create();
/** @var Playlist $playlist */
$playlist = Playlist::factory()->for($user)->create();
$playlist = Playlist::factory()->for(create_user())->create();
$playlist->songs()->attach(Song::factory(5)->create());
$this->getAs('api/playlists/' . $playlist->id . '/songs')
@ -99,10 +98,8 @@ class PlaylistSongTest extends TestCase
public function testNonOwnerCannotModifyPlaylist(): void
{
$user = User::factory()->create();
/** @var Playlist $playlist */
$playlist = Playlist::factory()->for($user)->create();
$playlist = Playlist::factory()->for(create_user())->create();
/** @var Song $song */
$song = Song::factory()->create();

View file

@ -4,11 +4,12 @@ namespace Tests\Feature;
use App\Models\Playlist;
use App\Models\Song;
use App\Models\User;
use App\Values\SmartPlaylistRule;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class PlaylistTest extends TestCase
{
private const JSON_STRUCTURE = [
@ -24,8 +25,7 @@ class PlaylistTest extends TestCase
public function testListing(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
Playlist::factory()->for($user)->count(3)->create();
$this->getAs('api/playlists', $user)
@ -35,8 +35,7 @@ class PlaylistTest extends TestCase
public function testCreatingPlaylist(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var array<Song>|Collection $songs */
$songs = Song::factory(4)->create();
@ -59,8 +58,7 @@ class PlaylistTest extends TestCase
public function testCreatingSmartPlaylist(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$rule = SmartPlaylistRule::make([
'model' => 'artist.name',

View file

@ -2,10 +2,11 @@
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
use function Tests\create_user;
class ProfileTest extends TestCase
{
public function testUpdateProfileRequiresCurrentPassword(): void
@ -19,8 +20,7 @@ class ProfileTest extends TestCase
public function testUpdateProfileWithoutNewPassword(): void
{
/** @var User $user */
$user = User::factory()->create(['password' => Hash::make('secret')]);
$user = create_user(['password' => Hash::make('secret')]);
$this->putAs('api/me', [
'name' => 'Foo',
@ -37,8 +37,7 @@ class ProfileTest extends TestCase
public function testUpdateProfileWithNewPassword(): void
{
/** @var User $user */
$user = User::factory()->create(['password' => Hash::make('secret')]);
$user = create_user(['password' => Hash::make('secret')]);
$token = $this->putAs('api/me', [
'name' => 'Foo',

View file

@ -4,9 +4,10 @@ namespace Tests\Feature;
use App\Models\QueueState;
use App\Models\Song;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_user;
class QueueTest extends TestCase
{
public const QUEUE_STATE_JSON_STRUCTURE = [
@ -35,8 +36,7 @@ class QueueTest extends TestCase
public function testUpdateStateWithoutExistingState(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
self::assertDatabaseMissing(QueueState::class, ['user_id' => $user->id]);

View file

@ -3,15 +3,15 @@
namespace Tests\Feature;
use App\Models\Interaction;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_user;
class RecentlyPlayedSongTest extends TestCase
{
public function testIndex(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
Interaction::factory(5)->for($user)->create();

View file

@ -8,14 +8,15 @@ use App\Services\LastfmService;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
class ScrobbleTest extends TestCase
{
public function testLastfmScrobble(): void
{
$this->withoutEvents();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $song */
$song = Song::factory()->create();

View file

@ -3,12 +3,13 @@
namespace Tests\Feature;
use App\Models\Setting;
use App\Models\User;
use App\Services\MediaScanner;
use App\Values\ScanResultCollection;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_admin;
class SettingTest extends TestCase
{
private MediaScanner|MockInterface $mediaScanner;
@ -22,13 +23,10 @@ class SettingTest extends TestCase
public function testSaveSettings(): void
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->mediaScanner->shouldReceive('scan')->once()
->andReturn(ScanResultCollection::create());
$this->putAs('/api/settings', ['media_path' => __DIR__], $admin)
$this->putAs('/api/settings', ['media_path' => __DIR__], create_admin())
->assertSuccessful();
self::assertSame(__DIR__, Setting::get('media_path'));

View file

@ -3,19 +3,20 @@
namespace Tests\Feature;
use App\Models\Song;
use App\Models\User;
use App\Services\Streamers\DirectStreamerInterface;
use App\Services\TokenManager;
use App\Values\CompositeToken;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class SongPlayTest extends TestCase
{
public function testPlay(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var CompositeToken $token */
$token = app(TokenManager::class)->createCompositeToken($user);

View file

@ -5,10 +5,11 @@ namespace Tests\Feature;
use App\Models\Album;
use App\Models\Artist;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_admin;
class SongTest extends TestCase
{
public const JSON_STRUCTURE = [
@ -74,10 +75,7 @@ class SongTest extends TestCase
/** @var Collection|array<array-key, Song> $songs */
$songs = Song::factory(3)->create();
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->deleteAs('api/songs', ['songs' => $songs->pluck('id')->all()], $admin)
$this->deleteAs('api/songs', ['songs' => $songs->pluck('id')->all()], create_admin())
->assertNoContent();
$songs->each(fn (Song $song) => $this->assertModelMissing($song));
@ -96,9 +94,6 @@ class SongTest extends TestCase
public function testSingleUpdateAllInfoNoCompilation(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var Song $song */
$song = Song::factory()->create();
@ -112,7 +107,7 @@ class SongTest extends TestCase
'track' => 1,
'disc' => 2,
],
], $user)
], create_admin())
->assertOk();
/** @var Artist $artist */
@ -134,9 +129,6 @@ class SongTest extends TestCase
public function testSingleUpdateSomeInfoNoCompilation(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var Song $song */
$song = Song::factory()->create();
@ -151,7 +143,7 @@ class SongTest extends TestCase
'lyrics' => 'Lorem ipsum dolor sic amet.',
'track' => 1,
],
], $user)
], create_admin())
->assertOk();
// We don't expect the song's artist to change
@ -163,8 +155,6 @@ class SongTest extends TestCase
public function testMultipleUpdateNoCompilation(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
$songIds = Song::factory(3)->create()->pluck('id')->all();
$this->putAs('/api/songs', [
@ -176,7 +166,7 @@ class SongTest extends TestCase
'lyrics' => null,
'track' => 9999,
],
], $user)
], create_admin())
->assertOk();
/** @var Collection|array<array-key, Song> $songs */
@ -201,9 +191,6 @@ class SongTest extends TestCase
public function testMultipleUpdateCreatingNewAlbumsAndArtists(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var array<array-key, Song>|Collection $originalSongs */
$originalSongs = Song::factory(3)->create();
$originalSongIds = $originalSongs->pluck('id')->all();
@ -219,7 +206,7 @@ class SongTest extends TestCase
'lyrics' => 'Lorem ipsum dolor sic amet.',
'track' => 1,
],
], $user)
], create_admin())
->assertOk();
/** @var array<array-key, Song>|Collection $songs */
@ -240,9 +227,6 @@ class SongTest extends TestCase
public function testSingleUpdateAllInfoWithCompilation(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var Song $song */
$song = Song::factory()->create();
@ -257,7 +241,7 @@ class SongTest extends TestCase
'track' => 1,
'disc' => 2,
],
], $user)
], create_admin())
->assertOk();
/** @var Album $album */
@ -283,9 +267,6 @@ class SongTest extends TestCase
public function testUpdateSingleSongWithEmptyTrackAndDisc(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
/** @var Song $song */
$song = Song::factory()->create([
'track' => 12,
@ -298,7 +279,7 @@ class SongTest extends TestCase
'track' => null,
'disc' => null,
],
], $user)
], create_admin())
->assertOk();
$song->refresh();

View file

@ -3,16 +3,15 @@
namespace Tests\Feature;
use App\Models\Song;
use App\Models\User;
use Tests\TestCase;
use function Tests\create_admin;
class SongVisibilityTest extends TestCase
{
public function testChangingVisibilityIsForbiddenInCommunityEdition(): void
{
/** @var User $owner */
$owner = User::factory()->admin()->create();
$owner = create_admin();
Song::factory(3)->create();
$this->putAs('api/songs/make-public', ['songs' => Song::query()->pluck('id')->all()], $owner)

View file

@ -6,12 +6,14 @@ use App\Events\LibraryChanged;
use App\Exceptions\MediaPathNotSetException;
use App\Exceptions\SongUploadFailedException;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
use function Tests\create_admin;
use function Tests\test_path;
class UploadTest extends TestCase
{
private UploadedFile $file;
@ -43,10 +45,7 @@ class UploadTest extends TestCase
{
Setting::set('media_path');
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->postAs('/api/upload', ['file' => $this->file], $admin)->assertForbidden();
$this->postAs('/api/upload', ['file' => $this->file], create_admin())->assertForbidden();
}
public function testUploadSuccessful(): void
@ -54,10 +53,7 @@ class UploadTest extends TestCase
Event::fake(LibraryChanged::class);
Setting::set('media_path', public_path('sandbox/media'));
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->postAs('/api/upload', ['file' => $this->file], $admin)->assertJsonStructure(['song', 'album']);
$this->postAs('/api/upload', ['file' => $this->file], create_admin())->assertJsonStructure(['song', 'album']);
Event::assertDispatched(LibraryChanged::class);
}
}

View file

@ -8,6 +8,8 @@ use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Tests\TestCase;
use function Tests\create_admin;
class UserInvitationTest extends TestCase
{
private const JSON_STRUCTURE = ['id', 'name', 'email', 'is_admin'];
@ -16,13 +18,10 @@ class UserInvitationTest extends TestCase
{
Mail::fake();
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->postAs('api/invitations', [
'emails' => ['foo@bar.io', 'bar@baz.ai'],
'is_admin' => true,
], $admin)
], create_admin())
->assertSuccessful()
->assertJsonStructure(['*' => self::JSON_STRUCTURE]);
@ -33,12 +32,7 @@ class UserInvitationTest extends TestCase
{
Mail::fake();
/** @var User $admin */
$admin = User::factory()->create();
$this->postAs('api/invitations', [
'emails' => ['foo@bar.io', 'bar@baz.ai'],
], $admin)
$this->postAs('api/invitations', ['emails' => ['foo@bar.io', 'bar@baz.ai']])
->assertForbidden();
Mail::assertNothingQueued();
@ -55,12 +49,9 @@ class UserInvitationTest extends TestCase
public function testRevoke(): void
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
$prospect = self::createProspect();
$this->deleteAs('api/invitations', ['email' => $prospect->email], $admin)
$this->deleteAs('api/invitations', ['email' => $prospect->email], create_admin())
->assertSuccessful();
self::assertModelMissing($prospect);
@ -95,10 +86,7 @@ class UserInvitationTest extends TestCase
private static function createProspect(): User
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
return User::factory()->for($admin, 'invitedBy')->create([
return User::factory()->for(create_admin(), 'invitedBy')->create([
'invitation_token' => Str::uuid()->toString(),
'invited_at' => now(),
]);

View file

@ -6,6 +6,9 @@ use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
use function Tests\create_admin;
use function Tests\create_user;
class UserTest extends TestCase
{
public function testNonAdminCannotCreateUser(): void
@ -20,8 +23,7 @@ class UserTest extends TestCase
public function testAdminCreatesUser(): void
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
$admin = create_admin();
$this->postAs('api/user', [
'name' => 'Foo',
@ -42,11 +44,8 @@ class UserTest extends TestCase
public function testAdminUpdatesUser(): void
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
/** @var User $user */
$user = User::factory()->admin()->create(['password' => 'secret']);
$admin = create_admin();
$user = create_admin(['password' => 'secret']);
$this->putAs("api/user/$user->id", [
'name' => 'Foo',
@ -66,22 +65,16 @@ class UserTest extends TestCase
public function testAdminDeletesUser(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var User $admin */
$admin = User::factory()->admin()->create();
$this->deleteAs("api/user/$user->id", [], $admin);
$this->deleteAs("api/user/$user->id", [], create_admin());
self::assertModelMissing($user);
}
public function testSeppukuNotAllowed(): void
public function testSelfDeletionNotAllowed(): void
{
/** @var User $admin */
$admin = User::factory()->admin()->create();
$admin = create_admin();
// A user can't delete himself
$this->deleteAs("api/user/$admin->id", [], $admin)->assertForbidden();
self::assertModelExists($admin);
}

View file

@ -2,16 +2,16 @@
namespace Tests\Integration\Casts;
use App\Models\User;
use App\Values\UserPreferences;
use Tests\TestCase;
use function Tests\create_user;
class UserPreferencesCastTest extends TestCase
{
public function testCast(): void
{
/** @var User $user */
$user = User::factory()->create([
$user = create_user([
'preferences' => [
'lastfm_session_key' => 'foo',
],

View file

@ -14,6 +14,8 @@ use Mockery;
use phpmock\mockery\PHPMockery;
use Tests\TestCase;
use function Tests\test_path;
class StreamerFactoryTest extends TestCase
{
private StreamerFactory $streamerFactory;

View file

@ -6,6 +6,8 @@ use App\Models\Song;
use App\Models\SongZipArchive;
use Tests\TestCase;
use function Tests\test_path;
class SongZipArchiveTest extends TestCase
{
public function testAddSongIntoArchive(): void

View file

@ -11,6 +11,8 @@ use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
use function Tests\test_path;
class ApplicationInformationServiceTest extends TestCase
{
public function testGetLatestVersionNumber(): void

View file

@ -7,6 +7,8 @@ use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Tests\TestCase;
use function Tests\test_path;
class FileScannerTest extends TestCase
{
private FileScanner $scanner;

View file

@ -7,11 +7,12 @@ use App\Events\MultipleSongsUnliked;
use App\Events\SongLikeToggled;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class InteractionServiceTest extends TestCase
{
private InteractionService $interactionService;
@ -52,9 +53,7 @@ class InteractionServiceTest extends TestCase
/** @var Collection $songs */
$songs = Song::factory(2)->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->interactionService->likeMany($songs, $user);
@ -72,9 +71,7 @@ class InteractionServiceTest extends TestCase
public function testUnlikeMultipleSongs(): void
{
$this->expectsEvents(MultipleSongsUnliked::class);
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Collection $interactions */
$interactions = Interaction::factory(3)->for($user)->create(['liked' => true]);

View file

@ -7,6 +7,8 @@ use App\Services\MediaMetadataService;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
use function Tests\test_path;
class MediaMetadataServiceTest extends TestCase
{
public function setUp(): void

View file

@ -9,7 +9,6 @@ use App\Models\Album;
use App\Models\Artist;
use App\Models\Setting;
use App\Models\Song;
use App\Models\User;
use App\Services\FileScanner;
use App\Services\MediaScanner;
use App\Values\ScanConfiguration;
@ -18,6 +17,8 @@ use Illuminate\Support\Arr;
use Mockery;
use Tests\TestCase;
use function Tests\create_admin;
class MediaScannerTest extends TestCase
{
private MediaScanner $scanner;
@ -39,8 +40,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$owner = create_admin();
$this->scanner->scan(ScanConfiguration::make(owner: $owner));
// Standard mp3 files under root path should be recognized
@ -95,9 +95,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$config = ScanConfiguration::make(owner: $owner);
$config = ScanConfiguration::make(owner: create_admin());
$this->scanner->scan($config);
/** @var Song $song */
@ -113,9 +111,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$config = ScanConfiguration::make(owner: $owner);
$config = ScanConfiguration::make(owner: create_admin());
$this->scanner->scan($config);
@ -138,8 +134,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$owner = create_admin();
$this->scanner->scan(ScanConfiguration::make(owner: $owner));
/** @var Song $song */
@ -150,9 +145,7 @@ class MediaScannerTest extends TestCase
'lyrics' => 'Booom Wroooom',
]);
/** @var User $anotherOwner */
$anotherOwner = User::factory()->admin()->create();
$this->scanner->scan(ScanConfiguration::make(owner: $anotherOwner, force: true));
$this->scanner->scan(ScanConfiguration::make(owner: create_admin(), force: true));
$song->refresh();
@ -166,8 +159,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$owner = create_admin();
$this->scanner->scan(ScanConfiguration::make(owner: $owner));
/** @var Song $song */
@ -190,8 +182,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$owner = create_admin();
$this->scanner->scan(ScanConfiguration::make(owner: $owner));
/** @var Song $song */
@ -216,14 +207,11 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(LibraryChanged::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$path = $this->path('/blank.mp3');
$this->scanner->scanWatchRecord(
new InotifyWatchRecord("CLOSE_WRITE,CLOSE $path"),
ScanConfiguration::make(owner: $owner)
ScanConfiguration::make(owner: create_admin())
);
self::assertDatabaseHas(Song::class, ['path' => $path]);
@ -233,15 +221,12 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(LibraryChanged::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
/** @var Song $song */
$song = Song::factory()->create();
$this->scanner->scanWatchRecord(
new InotifyWatchRecord("DELETE $song->path"),
ScanConfiguration::make(owner: $owner)
ScanConfiguration::make(owner: create_admin())
);
self::assertModelMissing($song);
@ -251,9 +236,7 @@ class MediaScannerTest extends TestCase
{
$this->expectsEvents(LibraryChanged::class, MediaScanCompleted::class);
/** @var User $owner */
$owner = User::factory()->admin()->create();
$config = ScanConfiguration::make(owner: $owner);
$config = ScanConfiguration::make(owner: create_admin());
$this->scanner->scan($config);
$this->scanner->scanWatchRecord(new InotifyWatchRecord("MOVED_FROM,ISDIR $this->mediaPath/subdir"), $config);
@ -298,9 +281,7 @@ class MediaScannerTest extends TestCase
public function testOptionallyIgnoreHiddenFiles(): void
{
/** @var User $owner */
$owner = User::factory()->admin()->create();
$config = ScanConfiguration::make(owner: $owner);
$config = ScanConfiguration::make(owner: create_admin());
config(['koel.ignore_dot_files' => false]);
$this->scanner->scan($config);

View file

@ -5,13 +5,14 @@ namespace Tests\Integration\Services;
use App\Models\Playlist;
use App\Models\PlaylistFolder;
use App\Models\Song;
use App\Models\User;
use App\Services\PlaylistService;
use App\Values\SmartPlaylistRuleGroupCollection;
use Illuminate\Support\Collection;
use Tests\TestCase;
use Webmozart\Assert\InvalidArgumentException;
use function Tests\create_user;
class PlaylistServiceTest extends TestCase
{
private PlaylistService $service;
@ -25,8 +26,7 @@ class PlaylistServiceTest extends TestCase
public function testCreatePlaylist(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$playlist = $this->service->createPlaylist('foo', $user);
@ -40,8 +40,7 @@ class PlaylistServiceTest extends TestCase
/** @var array<array-key, Song>|Collection $songs */
$songs = Song::factory(3)->create();
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$playlist = $this->service->createPlaylist('foo', $user, null, $songs->pluck('id')->all());
@ -67,8 +66,7 @@ class PlaylistServiceTest extends TestCase
],
]);
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$playlist = $this->service->createPlaylist('foo', $user, null, [], $rules);
@ -94,12 +92,9 @@ class PlaylistServiceTest extends TestCase
/** @var PlaylistFolder $folder */
$folder = PlaylistFolder::factory()->create();
/** @var User $user */
$user = User::factory()->create();
self::expectException(InvalidArgumentException::class);
$this->service->createPlaylist('foo', $user, $folder);
$this->service->createPlaylist('foo', create_user(), $folder);
}
public function testUpdateSimplePlaylist(): void

View file

@ -4,10 +4,11 @@ namespace Tests\Integration\Services;
use App\Models\QueueState;
use App\Models\Song;
use App\Models\User;
use App\Services\QueueService;
use Tests\TestCase;
use function Tests\create_user;
class QueueServiceTest extends TestCase
{
private QueueService $service;
@ -39,8 +40,7 @@ class QueueServiceTest extends TestCase
public function testCreateQueueState(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$this->assertDatabaseMissing(QueueState::class, [
'user_id' => $user->id,

View file

@ -12,6 +12,9 @@ use App\Services\SmartPlaylistService;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_admin;
use function Tests\create_user;
class SmartPlaylistServiceTest extends TestCase
{
private SmartPlaylistService $service;
@ -292,8 +295,7 @@ class SmartPlaylistServiceTest extends TestCase
public function testPlayCountIsGreaterThan(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$matches = Song::factory()->count(2)->create();
$notMatch = Song::factory()->create();
@ -330,8 +332,7 @@ class SmartPlaylistServiceTest extends TestCase
public function testLastPlayedAtIsInLast(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$matches = Song::factory()->count(2)->create();
$notMatch = Song::factory()->create();
@ -369,8 +370,7 @@ class SmartPlaylistServiceTest extends TestCase
public function testLastPlayedNotInLast(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$matches = Song::factory()->count(2)->create();
$notMatch = Song::factory()->create();
@ -408,8 +408,7 @@ class SmartPlaylistServiceTest extends TestCase
public function testLastPlayedIs(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$matches = Song::factory()->count(2)->create();
$notMatch = Song::factory()->create();
@ -539,7 +538,7 @@ class SmartPlaylistServiceTest extends TestCase
{
/** @var Playlist $playlist */
$playlist = Playlist::factory()
->for($playlistOwner ?? User::factory()->create())
->for($playlistOwner ?? create_admin())
->create(['rules' => $rules]);
self::assertEqualsCanonicalizing(

View file

@ -2,12 +2,13 @@
namespace Tests\Integration\Services;
use App\Models\User;
use App\Services\TokenManager;
use Illuminate\Support\Facades\Cache;
use Laravel\Sanctum\PersonalAccessToken;
use Tests\TestCase;
use function Tests\create_user;
class TokenManagerTest extends TestCase
{
private TokenManager $tokenManager;
@ -21,18 +22,14 @@ class TokenManagerTest extends TestCase
public function testCreateTokenWithAllAbilities(): void
{
/** @var User $user */
$user = User::factory()->create();
$token = $this->tokenManager->createToken($user);
$token = $this->tokenManager->createToken(create_user());
self::assertTrue($token->accessToken->can('*'));
}
public function testCreateTokenWithSpecificAbilities(): void
{
/** @var User $user */
$user = User::factory()->create();
$token = $this->tokenManager->createToken($user, ['audio']);
$token = $this->tokenManager->createToken(create_user(), ['audio']);
self::assertTrue($token->accessToken->can('audio'));
self::assertFalse($token->accessToken->can('video'));
@ -41,9 +38,7 @@ class TokenManagerTest extends TestCase
public function testCreateCompositionToken(): void
{
/** @var User $user */
$user = User::factory()->create();
$token = $this->tokenManager->createCompositeToken($user);
$token = $this->tokenManager->createCompositeToken(create_user());
self::assertModelExists(PersonalAccessToken::findToken($token->apiToken));
@ -57,9 +52,7 @@ class TokenManagerTest extends TestCase
public function testDeleteCompositionToken(): void
{
/** @var User $user */
$user = User::factory()->create();
$token = $this->tokenManager->createCompositeToken($user);
$token = $this->tokenManager->createCompositeToken(create_user());
$this->tokenManager->deleteCompositionToken($token->apiToken);
@ -70,8 +63,7 @@ class TokenManagerTest extends TestCase
public function testDestroyTokens(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$user->createToken('foo');
$user->createToken('bar');
@ -84,9 +76,7 @@ class TokenManagerTest extends TestCase
public function testDeleteTokenByPlainTextToken(): void
{
/** @var User $user */
$user = User::factory()->create();
$token = $this->tokenManager->createToken($user);
$token = $this->tokenManager->createToken(create_user());
self::assertModelExists($token->accessToken);
$this->tokenManager->deleteTokenByPlainTextToken($token->plainTextToken);
@ -96,8 +86,7 @@ class TokenManagerTest extends TestCase
public function testGetUserFromPlainTextToken(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$token = $this->tokenManager->createToken($user);
self::assertTrue($user->is($this->tokenManager->getUserFromPlainTextToken($token->plainTextToken)));
@ -105,9 +94,7 @@ class TokenManagerTest extends TestCase
public function testReplaceApiToken(): void
{
/** @var User $user */
$user = User::factory()->create();
$oldToken = $this->tokenManager->createToken($user);
$oldToken = $this->tokenManager->createToken(create_user());
$newToken = $this->tokenManager->refreshApiToken($oldToken->plainTextToken);
self::assertModelMissing($oldToken->accessToken);

View file

@ -5,12 +5,14 @@ namespace Tests\Integration\Services;
use App\Exceptions\MediaPathNotSetException;
use App\Exceptions\SongUploadFailedException;
use App\Models\Setting;
use App\Models\User;
use App\Services\UploadService;
use Illuminate\Http\UploadedFile;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class UploadServiceTest extends TestCase
{
private UploadService $service;
@ -26,30 +28,22 @@ class UploadServiceTest extends TestCase
{
Setting::set('media_path');
/** @var User $user */
$user = User::factory()->create();
self::expectException(MediaPathNotSetException::class);
$this->service->handleUploadedFile(Mockery::mock(UploadedFile::class), $user);
$this->service->handleUploadedFile(Mockery::mock(UploadedFile::class), create_user());
}
public function testHandleUploadedFileFails(): void
{
Setting::set('media_path', public_path('sandbox/media'));
/** @var User $user */
$user = User::factory()->create();
self::expectException(SongUploadFailedException::class);
$this->service->handleUploadedFile(UploadedFile::fake()->create('fake.mp3'), $user);
$this->service->handleUploadedFile(UploadedFile::fake()->create('fake.mp3'), create_user());
}
public function testHandleUploadedFile(): void
{
Setting::set('media_path', public_path('sandbox/media'));
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
$song = $this->service->handleUploadedFile(UploadedFile::fromFile(test_path('songs/full.mp3')), $user); //@phpstan-ignore-line

View file

@ -6,11 +6,13 @@ use App\Exceptions\InvitationNotFoundException;
use App\Mail\UserInvite;
use App\Models\User;
use App\Services\UserInvitationService;
use Hash;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Tests\TestCase;
use function Tests\create_admin;
class UserInvitationServiceTest extends TestCase
{
private UserInvitationService $service;
@ -27,9 +29,7 @@ class UserInvitationServiceTest extends TestCase
Mail::fake();
$emails = ['foo@bar.com', 'bar@baz.io'];
/** @var User $user */
$user = User::factory()->admin()->create();
$user = create_admin();
$this->service
->invite($emails, true, $user)
@ -48,9 +48,7 @@ class UserInvitationServiceTest extends TestCase
public function testGetUserProspectByToken(): void
{
$token = Str::uuid()->toString();
/** @var User $user */
$user = User::factory()->admin()->create();
$user = create_admin();
$prospect = User::factory()->for($user, 'invitedBy')->create([
'invitation_token' => $token,
@ -68,8 +66,7 @@ class UserInvitationServiceTest extends TestCase
public function testRevokeByEmail(): void
{
/** @var User $user */
$user = User::factory()->admin()->create();
$user = create_admin();
/** @var User $prospect */
$prospect = User::factory()->for($user, 'invitedBy')->create([
@ -85,9 +82,7 @@ class UserInvitationServiceTest extends TestCase
public function testAccept(): void
{
$token = Str::uuid()->toString();
/** @var User $user */
$user = User::factory()->admin()->create();
$user = create_admin();
User::factory()->for($user, 'invitedBy')->create([
'invitation_token' => $token,

View file

@ -8,6 +8,8 @@ use Illuminate\Contracts\Console\Kernel as Artisan;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\DB;
use function Tests\test_path;
trait CreatesApplication
{
protected string $mediaPath;

View file

@ -5,6 +5,8 @@ namespace Tests\Traits;
use App\Models\User;
use Illuminate\Testing\TestResponse;
use function Tests\create_user;
trait MakesHttpRequests
{
/**
@ -16,8 +18,7 @@ trait MakesHttpRequests
private function jsonAs(?User $user, string $method, $uri, array $data = [], array $headers = []): TestResponse
{
/** @var User $user */
$user = $user ?: User::factory()->create();
$user ??= create_user();
$this->withToken($user->createToken('koel')->plainTextToken);
return $this->json($method, $uri, $data, $headers);

View file

@ -4,23 +4,21 @@ namespace Tests\Unit\Jobs;
use App\Jobs\ScrobbleJob;
use App\Models\Song;
use App\Models\User;
use App\Services\LastfmService;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
class ScrobbleJobTest extends TestCase
{
public function testHandle(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $song */
$song = Song::factory()->make();
$job = new ScrobbleJob($user, $song, 100);
$lastfm = Mockery::mock(LastfmService::class);
$lastfm->shouldReceive('scrobble')

View file

@ -5,21 +5,20 @@ namespace Tests\Unit\Listeners;
use App\Events\PlaybackStarted;
use App\Listeners\UpdateLastfmNowPlaying;
use App\Models\Song;
use App\Models\User;
use App\Services\LastfmService;
use Mockery;
use Tests\TestCase;
use function Tests\create_user;
class UpdateLastfmNowPlayingTest extends TestCase
{
public function testUpdateNowPlayingStatus(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
/** @var Song $song */
$song = Song::factory()->create();
$lastfm = Mockery::mock(LastfmService::class, ['enabled' => true]);
$lastfm->shouldReceive('updateNowPlaying')

View file

@ -10,6 +10,8 @@ use Carbon\Carbon;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
use function Tests\test_path;
class WriteSyncLogTest extends TestCase
{
private WriteSyncLog $listener;

View file

@ -6,6 +6,8 @@ use App\Models\Artist;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
use function Tests\test_path;
class ArtistTest extends TestCase
{
public function testExistingArtistCanBeRetrievedUsingName(): void

View file

@ -10,6 +10,8 @@ use GuzzleHttp\Psr7\Response;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
use function Tests\test_path;
class LastfmClientTest extends TestCase
{
public function testGetSessionKey(): void

View file

@ -5,7 +5,6 @@ namespace Tests\Unit\Services;
use App\Models\Album;
use App\Models\Artist;
use App\Models\Song;
use App\Models\User;
use App\Services\ApiClients\LastfmClient;
use App\Services\LastfmService;
use Illuminate\Support\Facades\File;
@ -14,6 +13,9 @@ use Mockery\LegacyMockInterface;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\create_user;
use function Tests\test_path;
class LastfmServiceTest extends TestCase
{
private LastfmClient|MockInterface|LegacyMockInterface $client;
@ -116,8 +118,7 @@ class LastfmServiceTest extends TestCase
public function testScrobble(): void
{
/** @var User $user */
$user = User::factory()->create([
$user = create_user([
'preferences' => [
'lastfm_session_key' => 'my_key',
],
@ -149,8 +150,7 @@ class LastfmServiceTest extends TestCase
/** @dataProvider provideToggleLoveTrackData */
public function testToggleLoveTrack(bool $love, string $method): void
{
/** @var User $user */
$user = User::factory()->create([
$user = create_user([
'preferences' => [
'lastfm_session_key' => 'my_key',
],
@ -173,8 +173,7 @@ class LastfmServiceTest extends TestCase
public function testUpdateNowPlaying(): void
{
/** @var User $user */
$user = User::factory()->create([
$user = create_user([
'preferences' => [
'lastfm_session_key' => 'my_key',
],

View file

@ -4,11 +4,12 @@ namespace Tests\Unit\Services;
use App\Models\Playlist;
use App\Models\PlaylistFolder;
use App\Models\User;
use App\Services\PlaylistFolderService;
use Illuminate\Support\Collection;
use Tests\TestCase;
use function Tests\create_user;
class PlaylistFolderServiceTest extends TestCase
{
private PlaylistFolderService $service;
@ -22,8 +23,7 @@ class PlaylistFolderServiceTest extends TestCase
public function testCreate(): void
{
/** @var User $user */
$user = User::factory()->create();
$user = create_user();
self::assertCount(0, $user->playlist_folders);

View file

@ -7,6 +7,8 @@ use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Tests\TestCase;
use function Tests\test_path;
class SimpleLrcReaderTest extends TestCase
{
private SimpleLrcReader $reader;

View file

@ -12,6 +12,8 @@ use Mockery\LegacyMockInterface;
use Mockery\MockInterface;
use Tests\TestCase;
use function Tests\test_path;
class SpotifyServiceTest extends TestCase
{
private SpotifyService $service;

View file

@ -11,6 +11,8 @@ use Illuminate\Support\Facades\File;
use Mockery;
use Tests\TestCase;
use function Tests\test_path;
class YouTubeServiceTest extends TestCase
{
public function testSearchVideosRelatedToSong(): void

20
tests/helpers.php Normal file
View file

@ -0,0 +1,20 @@
<?php
namespace Tests;
use App\Models\User;
function create_user(array $attributes = []): User
{
return User::factory()->create($attributes);
}
function create_admin(array $attributes = []): User
{
return User::factory()->admin()->create($attributes);
}
function test_path(string $path = ''): string
{
return base_path('tests' . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR));
}