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

View file

@ -9,29 +9,29 @@ use App\Models\Setting;
use App\Models\User;
use App\Services\iTunesService;
use App\Services\LastfmService;
use App\Services\MediaCacheService;
use App\Services\YouTubeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use iTunes;
use Lastfm;
use MediaCache;
use YouTube;
class DataController extends Controller
{
private $lastfmService;
private $youTubeService;
private $iTunesService;
private $mediaCacheService;
public function __construct(
LastfmService $lastfmService,
YouTubeService $youTubeService,
iTunesService $iTunesService
iTunesService $iTunesService,
MediaCacheService $mediaCacheService
)
{
$this->lastfmService = $lastfmService;
$this->youTubeService = $youTubeService;
$this->iTunesService = $iTunesService;
$this->mediaCacheService = $mediaCacheService;
}
/**
@ -43,7 +43,7 @@ class DataController extends Controller
*/
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() : [],
'playlists' => Playlist::byCurrentUser()->orderBy('name')->get()->toArray(),
'interactions' => Interaction::byCurrentUser()->get(),

View file

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

View file

@ -2,7 +2,7 @@
namespace App\Providers;
use App\Services\MediaCache;
use App\Services\MediaCacheService;
use Illuminate\Support\ServiceProvider;
class MediaCacheServiceProvider extends ServiceProvider
@ -25,7 +25,7 @@ class MediaCacheServiceProvider extends ServiceProvider
public function register()
{
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\Artist;
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.
@ -23,7 +29,7 @@ class MediaCache
return $this->query();
}
return Cache::rememberForever($this->keyName, function () {
return $this->cache->rememberForever($this->keyName, function () {
return $this->query();
});
}
@ -47,6 +53,6 @@ class MediaCache
*/
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,
'Media' => App\Facades\Media::class,
'MediaCache' => App\Facades\MediaCache::class,
'Util' => App\Facades\Util::class,
'Lastfm' => App\Facades\Lastfm::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
}
}