Use proper DI for cache service

This commit is contained in:
Phan An 2018-08-19 16:56:56 +02:00
parent 1c76ff6d76
commit a837432a4e
8 changed files with 109 additions and 97 deletions

View file

@ -4,29 +4,26 @@ namespace App\Console\Commands;
use App\Models\Setting; use App\Models\Setting;
use App\Models\User; use App\Models\User;
use App\Services\MediaCacheService;
use DB; use DB;
use Exception; use Exception;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Jackiedo\DotenvEditor\Facades\DotenvEditor; use Jackiedo\DotenvEditor\Facades\DotenvEditor;
use MediaCache;
class Init extends Command class Init extends Command
{ {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'koel:init'; protected $signature = 'koel:init';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Install or upgrade Koel'; protected $description = 'Install or upgrade Koel';
private $mediaCacheService;
public function __construct(MediaCacheService $mediaCacheService)
{
parent::__construct();
$this->mediaCacheService = $mediaCacheService;
}
/** /**
* Execute the console command. * Execute the console command.
@ -69,8 +66,9 @@ class Init extends Command
$this->info('Migrating database'); $this->info('Migrating database');
Artisan::call('migrate', ['--force' => true]); Artisan::call('migrate', ['--force' => true]);
// Clean the media cache, just in case we did any media-related migration // Clean the media cache, just in case we did any media-related migration
MediaCache::clear(); $this->mediaCacheService->clear();
if (!User::count()) { if (!User::count()) {
$this->setUpAdminAccount(); $this->setUpAdminAccount();

View file

@ -9,29 +9,29 @@ use App\Models\Setting;
use App\Models\User; use App\Models\User;
use App\Services\iTunesService; use App\Services\iTunesService;
use App\Services\LastfmService; use App\Services\LastfmService;
use App\Services\MediaCacheService;
use App\Services\YouTubeService; use App\Services\YouTubeService;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use iTunes;
use Lastfm;
use MediaCache;
use YouTube;
class DataController extends Controller class DataController extends Controller
{ {
private $lastfmService; private $lastfmService;
private $youTubeService; private $youTubeService;
private $iTunesService; private $iTunesService;
private $mediaCacheService;
public function __construct( public function __construct(
LastfmService $lastfmService, LastfmService $lastfmService,
YouTubeService $youTubeService, YouTubeService $youTubeService,
iTunesService $iTunesService iTunesService $iTunesService,
MediaCacheService $mediaCacheService
) )
{ {
$this->lastfmService = $lastfmService; $this->lastfmService = $lastfmService;
$this->youTubeService = $youTubeService; $this->youTubeService = $youTubeService;
$this->iTunesService = $iTunesService; $this->iTunesService = $iTunesService;
$this->mediaCacheService = $mediaCacheService;
} }
/** /**
@ -43,7 +43,7 @@ class DataController extends Controller
*/ */
public function index(Request $request) public function index(Request $request)
{ {
return response()->json(MediaCache::get() + [ return response()->json($this->mediaCacheService->get() + [
'settings' => $request->user()->is_admin ? Setting::pluck('value', 'key')->all() : [], 'settings' => $request->user()->is_admin ? Setting::pluck('value', 'key')->all() : [],
'playlists' => Playlist::byCurrentUser()->orderBy('name')->get()->toArray(), 'playlists' => Playlist::byCurrentUser()->orderBy('name')->get()->toArray(),
'interactions' => Interaction::byCurrentUser()->get(), 'interactions' => Interaction::byCurrentUser()->get(),

View file

@ -2,16 +2,23 @@
namespace App\Listeners; namespace App\Listeners;
use MediaCache; use App\Services\MediaCacheService;
class ClearMediaCache class ClearMediaCache
{ {
private $mediaCacheService;
public function __construct(MediaCacheService $mediaCacheService)
{
$this->mediaCacheService = $mediaCacheService;
}
/** /**
* Fired every time a LibraryChanged event is triggered. * Fired every time a LibraryChanged event is triggered.
* Clears the media cache. * Clears the media cache.
*/ */
public function handle() public function handle()
{ {
MediaCache::clear(); $this->mediaCacheService->clear();
} }
} }

View file

@ -2,7 +2,7 @@
namespace App\Providers; namespace App\Providers;
use App\Services\MediaCache; use App\Services\MediaCacheService;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class MediaCacheServiceProvider extends ServiceProvider class MediaCacheServiceProvider extends ServiceProvider
@ -25,7 +25,7 @@ class MediaCacheServiceProvider extends ServiceProvider
public function register() public function register()
{ {
app()->singleton('MediaCache', function () { app()->singleton('MediaCache', function () {
return new MediaCache(); return new MediaCacheService();
}); });
} }
} }

View file

@ -5,11 +5,17 @@ namespace App\Services;
use App\Models\Album; use App\Models\Album;
use App\Models\Artist; use App\Models\Artist;
use App\Models\Song; use App\Models\Song;
use Cache; use Illuminate\Cache\Repository as Cache;
class MediaCache class MediaCacheService
{ {
protected $keyName = 'media_cache'; private $cache;
private $keyName = 'media_cache';
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
/** /**
* Get media data. * Get media data.
@ -23,7 +29,7 @@ class MediaCache
return $this->query(); return $this->query();
} }
return Cache::rememberForever($this->keyName, function () { return $this->cache->rememberForever($this->keyName, function () {
return $this->query(); return $this->query();
}); });
} }
@ -47,6 +53,6 @@ class MediaCache
*/ */
public function clear() public function clear()
{ {
Cache::forget($this->keyName); $this->cache->forget($this->keyName);
} }
} }

View file

@ -206,7 +206,6 @@ return [
'DotenvEditor' => Jackiedo\DotenvEditor\Facades\DotenvEditor::class, 'DotenvEditor' => Jackiedo\DotenvEditor\Facades\DotenvEditor::class,
'Media' => App\Facades\Media::class, 'Media' => App\Facades\Media::class,
'MediaCache' => App\Facades\MediaCache::class,
'Util' => App\Facades\Util::class, 'Util' => App\Facades\Util::class,
'Lastfm' => App\Facades\Lastfm::class, 'Lastfm' => App\Facades\Lastfm::class,
'YouTube' => App\Facades\YouTube::class, 'YouTube' => App\Facades\YouTube::class,

View file

@ -0,0 +1,70 @@
<?php
namespace Tests\Integration\Services;
use App\Models\Album;
use App\Models\Artist;
use App\Models\Song;
use App\Services\MediaCacheService;
use Illuminate\Cache\Repository as Cache;
use Mockery;
use Mockery\MockInterface;
use Tests\TestCase;
class MediaCacheServiceTest extends TestCase
{
/**
* @var MediaCacheService
*/
private $mediaCacheService;
/**
* @var Cache|MockInterface
*/
private $cache;
public function setUp()
{
parent::setUp();
$this->cache = Mockery::mock(Cache::class);
$this->mediaCacheService = new MediaCacheService($this->cache);
}
public function testGetIfCacheIsNotAvailable()
{
factory(Song::class, 5)->create();
$this->cache->shouldReceive('rememberForever')->andReturn([
'albums' => Album::orderBy('name')->get(),
'artists' => Artist::orderBy('name')->get(),
'songs' => Song::all(),
]);
$data = $this->mediaCacheService->get();
$this->assertCount(6, $data['albums']); // 5 new albums and the default Unknown Album
$this->assertCount(7, $data['artists']); // 5 new artists and the default Various and Unknown Artist
$this->assertCount(5, $data['songs']);
}
public function testGetIfCacheIsAvailable()
{
$this->cache->shouldReceive('rememberForever')->andReturn('dummy');
config(['koel.cache_media' => true]);
$data = $this->mediaCacheService->get();
$this->assertEquals('dummy', $data);
}
public function testCacheDisabled()
{
$this->cache->shouldReceive('rememberForever')->never();
config(['koel.cache_media' => false]);
$this->mediaCacheService->get();
}
}

View file

@ -1,68 +0,0 @@
<?php
namespace Tests\Integration\Services;
use App\Models\Album;
use App\Models\Artist;
use App\Models\Song;
use Cache;
use MediaCache;
use Tests\TestCase;
class MediaCacheTest extends TestCase
{
/** @test */
public function it_queries_fresh_data_from_database_or_use_the_cache()
{
// Given a database with artists, albums, and songs
factory(Song::class, 5)->create();
Cache::shouldReceive('rememberForever')->andReturn([
'albums' => Album::orderBy('name')->get(),
'artists' => Artist::orderBy('name')->get(),
'songs' => Song::all(),
]);
// When I get data from the MediaCache service
$data = MediaCache::get();
// Then a complete set of data is retrieved
$this->assertCount(6, $data['albums']); // 5 new albums and the default Unknown Album
$this->assertCount(7, $data['artists']); // 5 new artists and the default Various and Unknown Artist
$this->assertCount(5, $data['songs']);
}
/** @test */
public function it_get_the_cached_data_if_found()
{
// Given there are media data cached
Cache::shouldReceive('rememberForever')->andReturn('dummy');
// And koel.cache_media configuration is TRUE
config(['koel.cache_media' => true]);
// When I get data from the MediaCache service
$data = MediaCache::get();
// Then I receive the cached version
$this->assertEquals('dummy', $data);
}
/**
* @test
*
* @throws \Exception
*/
public function it_does_not_cache_queried_data_if_cache_media_is_configured_to_false()
{
Cache::shouldReceive('rememberForever')->never();
// Given koel.cache_media configuration is FALSE
config(['koel.cache_media' => false]);
// When I get data from the MediaCache service
MediaCache::get();
// Then I don't see the cache-related methods being called
}
}