Rewrite Lastfm tests

This commit is contained in:
Phan An 2018-08-19 18:05:10 +02:00
parent 5cf19b09aa
commit 69d68727b9
4 changed files with 112 additions and 106 deletions

View file

@ -9,52 +9,42 @@ use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
use Illuminate\Routing\Redirector;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\JWTAuth;
class LastfmController extends Controller
{
/*
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
private $lastfmService;
private $jwtAuth;
/**
* Construct the controller and inject the current auth.
*
* @param Guard $auth
*/
public function __construct(Guard $auth)
public function __construct(Guard $auth, LastfmService $lastfmService, JWTAuth $jwtAuth)
{
$this->auth = $auth;
$this->lastfmService = $lastfmService;
$this->jwtAuth = $jwtAuth;
}
/**
* Connect the current user to Last.fm.
*
* @param Redirector $redirector
* @param LastfmService $lastfm
* @param JWTAuth $auth
* @return RedirectResponse
*
* @return Redirector|RedirectResponse
* @throws JWTException
*/
public function connect(Redirector $redirector, LastfmService $lastfm, JWTAuth $auth = null)
public function connect()
{
abort_unless($lastfm->enabled(), 401, 'Koel is not configured to use with Last.fm yet.');
$auth = $auth ?: $this->app['tymon.jwt.auth'];
abort_unless($this->lastfmService->enabled(), 401, 'Koel is not configured to use with Last.fm yet.');
// A workaround to make sure Tymon's JWTAuth get the correct token via our custom
// "jwt-token" query string instead of the default "token".
// This is due to the problem that Last.fm returns the token via "token" as well.
$auth->parseToken('', '', 'jwt-token');
$this->jwtAuth->parseToken('', '', 'jwt-token');
return $redirector->to(
return redirect(
'https://www.last.fm/api/auth/?api_key='
.$lastfm->getKey()
.'&cb='.urlencode(route('lastfm.callback').'?jwt-token='.$auth->getToken())
.$this->lastfmService->getKey()
.'&cb='.urlencode(route('lastfm.callback').'?jwt-token='.$this->jwtAuth->getToken())
);
}
@ -62,14 +52,14 @@ class LastfmController extends Controller
* Serve the callback request from Last.fm.
*
* @param LastfmCallbackRequest $request
* @param LastfmService $lastfm
*
* @return Response
*/
public function callback(LastfmCallbackRequest $request, LastfmService $lastfm)
public function callback(LastfmCallbackRequest $request)
{
// Get the session key using the obtained token.
abort_unless($sessionKey = $lastfm->getSessionKey($request->token), 500, 'Invalid token key.');
$sessionKey = $this->lastfmService->getSessionKey($request->token);
abort_unless($sessionKey, 500, 'Invalid token key.');
$this->auth->user()->savePreference('lastfm_session_key', $sessionKey);

View file

@ -2,24 +2,12 @@
namespace Tests\Feature;
use App\Events\SongLikeToggled;
use App\Events\SongStartedPlaying;
use App\Http\Controllers\API\LastfmController;
use App\Http\Requests\API\LastfmCallbackRequest;
use App\Listeners\LoveTrackOnLastfm;
use App\Listeners\UpdateLastfmNowPlaying;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
use App\Services\LastfmService;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Routing\Redirector;
use Mockery as m;
use Mockery\MockInterface;
use Tymon\JWTAuth\JWTAuth;
class LastfmTest extends TestCase
@ -44,89 +32,40 @@ class LastfmTest extends TestCase
$this->assertEquals('foo', $user->lastfm_session_key);
}
/** @test */
public function user_can_connect_to_lastfm()
public function testConnectToLastfm()
{
/** @var Redirector|MockInterface $redirector */
$redirector = m::mock(Redirector::class);
$redirector->shouldReceive('to')->once();
/** @var Guard|MockInterface $guard */
$guard = m::mock(Guard::class, ['user' => factory(User::class)->create()]);
$auth = m::mock(JWTAuth::class, [
'parseToken' => '',
'getToken' => '',
$this->mockIocDependency(JWTAuth::class, [
'parseToken' => null,
'getToken' => 'foo',
]);
(new LastfmController($guard))->connect($redirector, app(LastfmService::class), $auth);
$this->getAsUser('api/lastfm/connect')
->assertRedirectedTo('https://www.last.fm/api/auth/?api_key=foo&cb=http%3A%2F%2Flocalhost%2Fapi%2Flastfm%2Fcallback%3Fjwt-token%3Dfoo');
}
public function testRetrieveAndStoreSessionKey()
{
/** @var LastfmCallbackRequest $request */
$request = m::mock(LastfmCallbackRequest::class);
$request->token = 'foo';
/** @var LastfmService $lastfm */
$lastfm = m::mock(LastfmService::class, ['getSessionKey' => 'bar']);
$lastfm = $this->mockIocDependency(LastfmService::class);
$lastfm->shouldReceive('getSessionKey')
->once()
->with('foo')
->andReturn('bar');
/** @var User $user */
$user = factory(User::class)->create();
/** @var Guard $guard */
$guard = m::mock(Guard::class, ['user' => $user]);
(new LastfmController($guard))->callback($request, $lastfm);
$this->getAsUser('api/lastfm/callback?token=foo', $user);
$user->refresh();
$this->assertEquals('bar', $user->lastfm_session_key);
}
public function testDisconnectUser()
{
/** @var User $user */
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$this->deleteAsUser('api/lastfm/disconnect', [], $user);
$user = User::find($user->id);
$user->refresh();
$this->assertNull($user->lastfm_session_key);
}
/**
* @throws Exception
*/
public function testLoveTrack()
{
$this->withoutEvents();
$this->createSampleMediaSet();
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$interaction = Interaction::create([
'user_id' => $user->id,
'song_id' => Song::first()->id,
]);
/** @var LastfmService|MockInterface $lastfm */
$lastfm = m::mock(LastfmService::class, ['enabled' => true]);
$lastfm->shouldReceive('toggleLoveTrack')
->once()
->with($interaction->song->title, $interaction->song->album->artist->name, 'bar', false);
(new LoveTrackOnLastfm($lastfm))->handle(new SongLikeToggled($interaction, $user));
}
/**
* @throws Exception
*/
public function testUpdateNowPlayingStatus()
{
$this->withoutEvents();
$this->createSampleMediaSet();
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$song = Song::first();
/** @var LastfmService|MockInterface $lastfm */
$lastfm = m::mock(LastfmService::class, ['enabled' => true]);
$lastfm->shouldReceive('updateNowPlaying')
->once()
->with($song->album->artist->name, $song->title, $song->album->name, $song->length, 'bar');
(new UpdateLastfmNowPlaying($lastfm))->handle(new SongStartedPlaying($song, $user));
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace Tests\Integration\Listeners;
use App\Events\SongLikeToggled;
use App\Listeners\LoveTrackOnLastfm;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
use App\Services\LastfmService;
use Exception;
use Mockery;
use Mockery\MockInterface;
use Tests\Feature\TestCase;
class LoveTrackOnLastfmTest extends TestCase
{
/**
* @throws Exception
*/
public function testHandle()
{
$this->withoutEvents();
$this->createSampleMediaSet();
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$interaction = Interaction::create([
'user_id' => $user->id,
'song_id' => Song::first()->id,
]);
/** @var LastfmService|MockInterface $lastfm */
$lastfm = Mockery::mock(LastfmService::class, ['enabled' => true]);
$lastfm->shouldReceive('toggleLoveTrack')
->once()
->with($interaction->song->title, $interaction->song->album->artist->name, 'bar', false);
(new LoveTrackOnLastfm($lastfm))->handle(new SongLikeToggled($interaction, $user));
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Tests\Integration\Listeners;
use App\Events\SongStartedPlaying;
use App\Listeners\UpdateLastfmNowPlaying;
use App\Models\Song;
use App\Models\User;
use App\Services\LastfmService;
use Exception;
use Mockery;
use Mockery\MockInterface;
use Tests\Feature\TestCase;
class UpdateLastfmNowPlayingTest extends TestCase
{
/**
* @throws Exception
*/
public function testUpdateNowPlayingStatus()
{
$this->withoutEvents();
$this->createSampleMediaSet();
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$song = Song::first();
/** @var LastfmService|MockInterface $lastfm */
$lastfm = Mockery::mock(LastfmService::class, ['enabled' => true]);
$lastfm->shouldReceive('updateNowPlaying')
->once()
->with($song->album->artist->name, $song->title, $song->album->name, $song->length, 'bar');
(new UpdateLastfmNowPlaying($lastfm))->handle(new SongStartedPlaying($song, $user));
}
}