what the fuck
This commit is contained in:
1 parent
c1b1c2f372
commit
72a99a5bcd
69 files changed
+7519
-558
No files matched your search
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service;
|
||||
|
||||
use App\Service\ExternalAlbumClient;
|
||||
use App\Service\ExternalProviderManager;
|
||||
use App\Service\LastFmClient;
|
||||
use App\Service\MusicBrainzClient;
|
||||
use App\Service\TidalClient;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class ExternalAlbumClientTest extends TestCase
|
||||
{
|
||||
public function testUnknownProviderFallsBackToLastFm(): void
|
||||
{
|
||||
$lastFm = $this->createMock(LastFmClient::class);
|
||||
$musicBrainz = $this->createMock(MusicBrainzClient::class);
|
||||
$tidal = $this->createMock(TidalClient::class);
|
||||
$providerManager = $this->createMock(ExternalProviderManager::class);
|
||||
|
||||
$providerManager->expects(self::atLeastOnce())
|
||||
->method('getEffectiveProvider')
|
||||
->willReturn('unknown-provider');
|
||||
|
||||
$lastFm->expects(self::once())
|
||||
->method('searchAlbums')
|
||||
->with('radiohead', 5, 1)
|
||||
->willReturn(['albums' => ['items' => []]]);
|
||||
$lastFm->expects(self::once())
|
||||
->method('getProviderName')
|
||||
->willReturn('lastfm');
|
||||
|
||||
$musicBrainz->expects(self::never())->method('searchAlbums');
|
||||
$tidal->expects(self::never())->method('searchAlbums');
|
||||
|
||||
$client = new ExternalAlbumClient($lastFm, $musicBrainz, $tidal, $providerManager);
|
||||
$result = $client->searchAlbums('radiohead', 5, 1);
|
||||
|
||||
self::assertSame(['albums' => ['items' => []]], $result);
|
||||
self::assertSame('lastfm', $client->getProviderName());
|
||||
}
|
||||
|
||||
public function testMusicBrainzProviderRoutesCallsToMusicBrainzClient(): void
|
||||
{
|
||||
$lastFm = $this->createMock(LastFmClient::class);
|
||||
$musicBrainz = $this->createMock(MusicBrainzClient::class);
|
||||
$tidal = $this->createMock(TidalClient::class);
|
||||
$providerManager = $this->createMock(ExternalProviderManager::class);
|
||||
|
||||
$providerManager->expects(self::atLeastOnce())
|
||||
->method('getEffectiveProvider')
|
||||
->willReturn('musicbrainz');
|
||||
|
||||
$musicBrainz->expects(self::once())
|
||||
->method('searchAlbums')
|
||||
->with('tool', 3, 2)
|
||||
->willReturn([
|
||||
'albums' => [
|
||||
'items' => [
|
||||
['id' => 'mbid:abc', 'name' => 'Lateralus'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$musicBrainz->expects(self::once())
|
||||
->method('getProviderName')
|
||||
->willReturn('musicbrainz');
|
||||
|
||||
$lastFm->expects(self::never())->method('searchAlbums');
|
||||
$tidal->expects(self::never())->method('searchAlbums');
|
||||
|
||||
$client = new ExternalAlbumClient($lastFm, $musicBrainz, $tidal, $providerManager);
|
||||
$result = $client->searchAlbums('tool', 3, 2);
|
||||
|
||||
self::assertSame('mbid:abc', $result['albums']['items'][0]['id'] ?? null);
|
||||
self::assertSame('musicbrainz', $client->getProviderName());
|
||||
}
|
||||
|
||||
public function testTidalProviderRoutesCallsToTidalClient(): void
|
||||
{
|
||||
$lastFm = $this->createMock(LastFmClient::class);
|
||||
$musicBrainz = $this->createMock(MusicBrainzClient::class);
|
||||
$tidal = $this->createMock(TidalClient::class);
|
||||
$providerManager = $this->createMock(ExternalProviderManager::class);
|
||||
|
||||
$providerManager->expects(self::atLeastOnce())
|
||||
->method('getEffectiveProvider')
|
||||
->willReturn('tidal');
|
||||
|
||||
$tidal->expects(self::once())
|
||||
->method('searchAlbums')
|
||||
->with('kanye', 4, 1)
|
||||
->willReturn([
|
||||
'albums' => [
|
||||
'items' => [
|
||||
['id' => 'tidal:123', 'name' => 'The College Dropout'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$tidal->expects(self::once())
|
||||
->method('getProviderName')
|
||||
->willReturn('tidal');
|
||||
|
||||
$lastFm->expects(self::never())->method('searchAlbums');
|
||||
$musicBrainz->expects(self::never())->method('searchAlbums');
|
||||
|
||||
$client = new ExternalAlbumClient($lastFm, $musicBrainz, $tidal, $providerManager);
|
||||
$result = $client->searchAlbums('kanye', 4, 1);
|
||||
|
||||
self::assertSame('tidal:123', $result['albums']['items'][0]['id'] ?? null);
|
||||
self::assertSame('tidal', $client->getProviderName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service;
|
||||
|
||||
use App\Repository\SettingRepository;
|
||||
use App\Service\MusicBrainzClient;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
final class MusicBrainzClientTest extends TestCase
|
||||
{
|
||||
public function testDetailedAlbumUsesCanonicalMusicBrainzUrlForOpenSourceLink(): void
|
||||
{
|
||||
$releaseId = '78eb2077-b86d-4382-9ce7-38f9260316f0';
|
||||
|
||||
$httpClient = $this->createMock(ClientInterface::class);
|
||||
$httpClient->expects(self::once())
|
||||
->method('request')
|
||||
->with(
|
||||
'GET',
|
||||
'https://musicbrainz.org/ws/2/release/' . $releaseId,
|
||||
self::callback(static function (array $options): bool {
|
||||
$query = $options['query'] ?? [];
|
||||
return ($query['fmt'] ?? null) === 'json';
|
||||
})
|
||||
)
|
||||
->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode([
|
||||
'id' => $releaseId,
|
||||
'title' => 'Reference Album',
|
||||
'artist-credit' => [
|
||||
['name' => 'Reference Artist'],
|
||||
],
|
||||
'media' => [[
|
||||
'position' => 1,
|
||||
'tracks' => [[
|
||||
'id' => 'track-1',
|
||||
'number' => '1',
|
||||
'title' => 'Reference Track',
|
||||
'length' => 180000,
|
||||
]],
|
||||
]],
|
||||
// External storefront URL should not be used as the "Open Source" link.
|
||||
'relations' => [[
|
||||
'url' => ['resource' => 'https://store.example.test/reference-album'],
|
||||
]],
|
||||
], JSON_THROW_ON_ERROR)));
|
||||
|
||||
$settings = $this->createMock(SettingRepository::class);
|
||||
$cache = new ArrayAdapter();
|
||||
|
||||
$client = new MusicBrainzClient($httpClient, $cache, $settings);
|
||||
$album = $client->getAlbumWithTracks('mbid:' . $releaseId);
|
||||
|
||||
self::assertIsArray($album);
|
||||
self::assertSame(
|
||||
'https://musicbrainz.org/release/' . $releaseId,
|
||||
$album['external_urls']['external'] ?? null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service;
|
||||
|
||||
use App\Repository\SettingRepository;
|
||||
use App\Service\TidalClient;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
final class TidalClientTest extends TestCase
|
||||
{
|
||||
public function testIsConfiguredRequiresClientIdAndSecret(): void
|
||||
{
|
||||
$http = $this->createMock(ClientInterface::class);
|
||||
$settings = $this->createMock(SettingRepository::class);
|
||||
$cache = new ArrayAdapter();
|
||||
|
||||
$client = new TidalClient($http, $cache, $settings, 'client-id-only', null, 'US');
|
||||
|
||||
self::assertFalse($client->isConfigured());
|
||||
}
|
||||
|
||||
public function testSearchAlbumsUsesClientCredentialsAndNormalizesPayload(): void
|
||||
{
|
||||
$http = $this->createMock(ClientInterface::class);
|
||||
$settings = $this->createMock(SettingRepository::class);
|
||||
$cache = new ArrayAdapter();
|
||||
|
||||
$call = 0;
|
||||
$http->expects(self::exactly(2))
|
||||
->method('request')
|
||||
->willReturnCallback(function (string $method, string $uri, array $options) use (&$call) {
|
||||
$call++;
|
||||
if ($call === 1) {
|
||||
self::assertSame('POST', $method);
|
||||
self::assertSame('https://auth.tidal.com/v1/oauth2/token', $uri);
|
||||
self::assertSame('client_credentials', $options['form_params']['grant_type'] ?? null);
|
||||
self::assertSame('tidal-client-id', $options['form_params']['client_id'] ?? null);
|
||||
self::assertSame('tidal-client-secret', $options['form_params']['client_secret'] ?? null);
|
||||
|
||||
return new Response(200, ['Content-Type' => 'application/json'], json_encode([
|
||||
'access_token' => 'token-abc',
|
||||
'expires_in' => 3600,
|
||||
'token_type' => 'Bearer',
|
||||
], JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
self::assertSame('GET', $method);
|
||||
self::assertStringContainsString('/searchResults/kanye%20west/relationships/albums', $uri);
|
||||
self::assertSame('US', $options['query']['countryCode'] ?? null);
|
||||
self::assertSame('albums', $options['query']['include'] ?? null);
|
||||
self::assertSame('Bearer token-abc', $options['headers']['Authorization'] ?? null);
|
||||
|
||||
return new Response(200, ['Content-Type' => 'application/vnd.api+json'], json_encode([
|
||||
'data' => [
|
||||
['type' => 'albums', 'id' => '251380836'],
|
||||
],
|
||||
'included' => [
|
||||
[
|
||||
'type' => 'albums',
|
||||
'id' => '251380836',
|
||||
'attributes' => [
|
||||
'title' => '4:44',
|
||||
'releaseDate' => '2017-06-30',
|
||||
'numberOfItems' => 10,
|
||||
'externalLinks' => [
|
||||
[
|
||||
'href' => 'https://tidal.com/browse/album/251380836',
|
||||
'meta' => ['type' => 'TIDAL_SHARING'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'relationships' => [
|
||||
'artists' => [
|
||||
'data' => [
|
||||
['type' => 'artists', 'id' => 'artist-1'],
|
||||
],
|
||||
],
|
||||
'genres' => [
|
||||
'data' => [
|
||||
['type' => 'genres', 'id' => 'genre-1'],
|
||||
],
|
||||
],
|
||||
'coverArt' => [
|
||||
'data' => [
|
||||
['type' => 'artworks', 'id' => 'art-1'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'artists',
|
||||
'id' => 'artist-1',
|
||||
'attributes' => ['name' => 'JAY-Z'],
|
||||
],
|
||||
[
|
||||
'type' => 'genres',
|
||||
'id' => 'genre-1',
|
||||
'attributes' => ['genreName' => 'hip hop'],
|
||||
],
|
||||
[
|
||||
'type' => 'artworks',
|
||||
'id' => 'art-1',
|
||||
'attributes' => [
|
||||
'files' => [
|
||||
['href' => 'https://cdn.example.test/160.jpg', 'meta' => ['width' => 160, 'height' => 160]],
|
||||
['href' => 'https://cdn.example.test/320.jpg', 'meta' => ['width' => 320, 'height' => 320]],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'links' => ['self' => '/searchResults/kanye west/relationships/albums'],
|
||||
], JSON_THROW_ON_ERROR));
|
||||
});
|
||||
|
||||
$client = new TidalClient($http, $cache, $settings, 'tidal-client-id', 'tidal-client-secret', 'US');
|
||||
$result = $client->searchAlbums('kanye west', 5, 1);
|
||||
|
||||
$items = $result['albums']['items'] ?? [];
|
||||
self::assertCount(1, $items);
|
||||
self::assertSame('tidal:251380836', $items[0]['id'] ?? null);
|
||||
self::assertSame('4:44', $items[0]['name'] ?? null);
|
||||
self::assertSame('JAY-Z', $items[0]['artists'][0]['name'] ?? null);
|
||||
self::assertSame('Hip Hop', $items[0]['genres'][0] ?? null);
|
||||
self::assertSame('2017-06-30', $items[0]['release_date'] ?? null);
|
||||
self::assertSame(10, $items[0]['total_tracks'] ?? null);
|
||||
self::assertSame('https://cdn.example.test/320.jpg', $items[0]['images'][0]['url'] ?? null);
|
||||
self::assertSame('https://tidal.com/browse/album/251380836', $items[0]['external_urls']['external'] ?? null);
|
||||
}
|
||||
|
||||
public function testGetAlbumWithTracksNormalizesTracksAndCoverArt(): void
|
||||
{
|
||||
$http = $this->createMock(ClientInterface::class);
|
||||
$settings = $this->createMock(SettingRepository::class);
|
||||
$cache = new ArrayAdapter();
|
||||
|
||||
$call = 0;
|
||||
$http->expects(self::exactly(2))
|
||||
->method('request')
|
||||
->willReturnCallback(function (string $method, string $uri, array $options) use (&$call) {
|
||||
$call++;
|
||||
if ($call === 1) {
|
||||
return new Response(200, ['Content-Type' => 'application/json'], json_encode([
|
||||
'access_token' => 'token-xyz',
|
||||
'expires_in' => 3600,
|
||||
'token_type' => 'Bearer',
|
||||
], JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
self::assertSame('GET', $method);
|
||||
self::assertStringContainsString('/albums/251380836', $uri);
|
||||
self::assertSame('artists,coverArt,genres,items', $options['query']['include'] ?? null);
|
||||
self::assertSame('US', $options['query']['countryCode'] ?? null);
|
||||
|
||||
return new Response(200, ['Content-Type' => 'application/vnd.api+json'], json_encode([
|
||||
'data' => [
|
||||
'type' => 'albums',
|
||||
'id' => '251380836',
|
||||
'attributes' => [
|
||||
'title' => '4:44',
|
||||
'releaseDate' => '2017-06-30',
|
||||
'numberOfItems' => 2,
|
||||
'externalLinks' => [
|
||||
[
|
||||
'href' => 'https://tidal.com/browse/album/251380836',
|
||||
'meta' => ['type' => 'TIDAL_SHARING'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'relationships' => [
|
||||
'artists' => [
|
||||
'data' => [
|
||||
['type' => 'artists', 'id' => 'artist-1'],
|
||||
],
|
||||
],
|
||||
'genres' => [
|
||||
'data' => [
|
||||
['type' => 'genres', 'id' => 'genre-1'],
|
||||
],
|
||||
],
|
||||
'coverArt' => [
|
||||
'data' => [
|
||||
['type' => 'artworks', 'id' => 'art-1'],
|
||||
],
|
||||
],
|
||||
'items' => [
|
||||
'data' => [
|
||||
['type' => 'tracks', 'id' => 'track-1', 'meta' => ['volumeNumber' => 1, 'trackNumber' => 1]],
|
||||
['type' => 'tracks', 'id' => 'track-2', 'meta' => ['volumeNumber' => 1, 'trackNumber' => 2]],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'included' => [
|
||||
['type' => 'artists', 'id' => 'artist-1', 'attributes' => ['name' => 'JAY-Z']],
|
||||
['type' => 'genres', 'id' => 'genre-1', 'attributes' => ['genreName' => 'hip hop']],
|
||||
[
|
||||
'type' => 'artworks',
|
||||
'id' => 'art-1',
|
||||
'attributes' => [
|
||||
'files' => [
|
||||
['href' => 'https://cdn.example.test/640.jpg', 'meta' => ['width' => 640, 'height' => 640]],
|
||||
],
|
||||
],
|
||||
],
|
||||
['type' => 'tracks', 'id' => 'track-1', 'attributes' => ['title' => 'Kill Jay Z', 'duration' => 'PT3M25S']],
|
||||
['type' => 'tracks', 'id' => 'track-2', 'attributes' => ['title' => 'The Story of O.J.', 'duration' => 'PT3M52S']],
|
||||
],
|
||||
'links' => ['self' => '/albums/251380836'],
|
||||
], JSON_THROW_ON_ERROR));
|
||||
});
|
||||
|
||||
$client = new TidalClient($http, $cache, $settings, 'tidal-client-id', 'tidal-client-secret', 'US');
|
||||
$album = $client->getAlbumWithTracks('tidal:251380836');
|
||||
|
||||
self::assertIsArray($album);
|
||||
self::assertSame('tidal:251380836', $album['id'] ?? null);
|
||||
self::assertSame('4:44', $album['name'] ?? null);
|
||||
self::assertSame('JAY-Z', $album['artists'][0]['name'] ?? null);
|
||||
self::assertSame('Hip Hop', $album['genres'][0] ?? null);
|
||||
self::assertSame('2017-06-30', $album['release_date'] ?? null);
|
||||
self::assertSame('https://cdn.example.test/640.jpg', $album['images'][0]['url'] ?? null);
|
||||
self::assertSame(2, $album['total_tracks'] ?? null);
|
||||
self::assertSame(2, $album['tracks']['total'] ?? null);
|
||||
self::assertSame('Kill Jay Z', $album['tracks']['items'][0]['name'] ?? null);
|
||||
self::assertSame(205000, $album['tracks']['items'][0]['duration_ms'] ?? null);
|
||||
self::assertSame(1, $album['tracks']['items'][0]['track_number'] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user