diff --git a/.travis.yml b/.travis.yml index f4b5a9f..6ec7d69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,19 @@ php: - hhvm - nightly +matrix: + fast_finish: true + allow_failures: + - php: nightly + before_script: - - composer install + - composer install --dev + - mkdir -p build/logs + - chmod +x bin/phpunit + - chmod +x bin/coveralls + +script: + - bin/phpunit --coverage-clover build/logs/clover.xml -script: phpunit --coverage-text +after_success: + - travis_retry bin/coveralls -v diff --git a/README.md b/README.md index ecaf9fb..f824594 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ examples in your browser: http://localhost/phpbrainz/examples/browse.php ?> ``` -**With Guzzle3** +**With Guzzle3 (deprecated)** ```php - ./tests/MusicBrainz/ + ./tests + + ./src/ + ./tests/ ./vendor/ @@ -24,15 +27,11 @@ - + + + + + diff --git a/src/MusicBrainz/Filters/AbstractFilter.php b/src/MusicBrainz/Filters/AbstractFilter.php index b4a2559..8675da9 100644 --- a/src/MusicBrainz/Filters/AbstractFilter.php +++ b/src/MusicBrainz/Filters/AbstractFilter.php @@ -75,4 +75,18 @@ public function createParameters(array $params = array()) return $params; } + + protected function toArray($object) + { + if(is_object($object)) { + return get_object_vars($object); + } + + if(is_array($object)) { + return $object; + } + + throw new \Exception('unable to convert to array'); + } + } diff --git a/src/MusicBrainz/Filters/ArtistFilter.php b/src/MusicBrainz/Filters/ArtistFilter.php index 2008b80..107e34c 100644 --- a/src/MusicBrainz/Filters/ArtistFilter.php +++ b/src/MusicBrainz/Filters/ArtistFilter.php @@ -51,10 +51,12 @@ public function parseResponse(array $response, MusicBrainz $brainz) $artists = array(); if (isset($response['artist'])) { foreach ($response['artist'] as $artist) { + $artist = $this->toArray($artist); $artists[] = new Artist($artist, $brainz); } } elseif (isset($response['artists'])) { foreach ($response['artists'] as $artist) { + $artist = $this->toArray($artist); $artists[] = new Artist($artist, $brainz); } } diff --git a/src/MusicBrainz/Filters/ReleaseGroupFilter.php b/src/MusicBrainz/Filters/ReleaseGroupFilter.php index 3440883..21edca1 100644 --- a/src/MusicBrainz/Filters/ReleaseGroupFilter.php +++ b/src/MusicBrainz/Filters/ReleaseGroupFilter.php @@ -56,6 +56,7 @@ public function parseResponse(array $response, MusicBrainz $brainz) $releaseGroups = array(); foreach ($response['release-groups'] as $releaseGroup) { + $releaseGroup = $this->toArray($releaseGroup); $releaseGroups[] = new ReleaseGroup($releaseGroup, $brainz); } diff --git a/src/MusicBrainz/HttpAdapters/GuzzleFiveAdapter.php b/src/MusicBrainz/HttpAdapters/GuzzleFiveAdapter.php index 86d983c..1d4652e 100644 --- a/src/MusicBrainz/HttpAdapters/GuzzleFiveAdapter.php +++ b/src/MusicBrainz/HttpAdapters/GuzzleFiveAdapter.php @@ -64,11 +64,21 @@ public function call($path, array $params = array(), array $options = array(), $ } } - $request = $this->client->createRequest('GET', $this->endpoint . '/' . $path, $requestOptions); + $response = $this->client->request('GET', $this->endpoint . '/' . $path, $requestOptions); // musicbrainz throttle sleep(1); - return $this->client->send($request)->json(); + $responseBody = $response->getBody()->getContents(); + $jsonResponse = \GuzzleHttp\json_decode($responseBody); + + if(json_last_error() === JSON_ERROR_NONE) { + if($returnArray) { + return get_object_vars($jsonResponse); + } + return $jsonResponse; + } + + throw new Exception('Expected JSON response. Got:' . $responseBody ); } } \ No newline at end of file diff --git a/src/MusicBrainz/HttpAdapters/GuzzleSixAdapter.php b/src/MusicBrainz/HttpAdapters/GuzzleSixAdapter.php new file mode 100644 index 0000000..6749c13 --- /dev/null +++ b/src/MusicBrainz/HttpAdapters/GuzzleSixAdapter.php @@ -0,0 +1,80 @@ +client = $client; + + if(filter_var($endpoint, FILTER_VALIDATE_URL)) { + $this->endpoint = $endpoint; + } + } + + /** + * Perform an HTTP request on MusicBrainz + * + * @param string $path + * @param array $params + * @param array $options + * @param bool $isAuthRequired + * @param bool $returnArray + * + * @return array|bool|float|int|string + * + * @throws Exception + */ + public function call( + $path, + array $params = array(), + array $options = array(), + $isAuthRequired = false, + $returnArray = false + ) { + if ($options['user-agent'] == '') { + throw new Exception('You must set a valid User Agent before accessing the MusicBrainz API'); + } + + $requestOptions = [ + 'headers' => [ + 'Accept' => 'application/json', + 'User-Agent' => $options['user-agent'] + ], + 'query' => $params + ]; + + if ($isAuthRequired) { + if ($options['user'] != NULL && $options['password'] != NULL) { + $requestOptions['auth'] = [ + 'username' => $options['user'], + 'password' => $options['password'], + CURLAUTH_DIGEST + ]; + } else { + throw new Exception('Authentication is required'); + } + } + + $request = $this->client->createRequest('GET', $this->endpoint . '/' . $path, $requestOptions); + + // musicbrainz throttle + sleep(1); + + return $this->client->send($request)->json(); + } +} \ No newline at end of file diff --git a/src/MusicBrainz/MusicBrainz.php b/src/MusicBrainz/MusicBrainz.php index 8b740f1..9a46997 100644 --- a/src/MusicBrainz/MusicBrainz.php +++ b/src/MusicBrainz/MusicBrainz.php @@ -17,7 +17,7 @@ class MusicBrainz /** * @var array */ - private static $validIncludes = array( + public static $validIncludes = array( 'artist' => array( "recordings", "releases", @@ -187,7 +187,7 @@ class MusicBrainz /** * @var array */ - private static $validBrowseIncludes = array( + public static $validBrowseIncludes = array( 'release' => array( "artist-credits", "labels", @@ -235,7 +235,7 @@ class MusicBrainz /** * @var array */ - private static $validReleaseTypes = array( + public static $validReleaseTypes = array( "nat", "album", "single", @@ -252,7 +252,7 @@ class MusicBrainz /** * @var array */ - private static $validReleaseStatuses = array( + public static $validReleaseStatuses = array( "official", "promotion", "bootleg", diff --git a/tests/MusicBrainz/Tests/MusicBrainzTest.php b/tests/MusicBrainz/Tests/MusicBrainzTest.php index d945602..07ee78d 100644 --- a/tests/MusicBrainz/Tests/MusicBrainzTest.php +++ b/tests/MusicBrainz/Tests/MusicBrainzTest.php @@ -2,23 +2,32 @@ namespace MusicBrainz\Tests; +use MusicBrainz\HttpAdapters\AbstractHttpAdapter; use MusicBrainz\HttpAdapters\GuzzleFiveAdapter; -use MusicBrainz\MusicBrainz; +use MusicBrainz; /** * @covers MusicBrainz\MusicBrainz */ class MusicBrainzTest extends \PHPUnit_Framework_TestCase { + const USERNAME = 'testuser'; + const PASSWORD = 'testpass'; /** * @var \MusicBrainz\MusicBrainz */ protected $brainz; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $httpAdapter; + public function setUp() { - /** @noinspection PhpParamsInspection */ - $this->brainz = new MusicBrainz(new GuzzleFiveAdapter($this->getMock('\GuzzleHttp\ClientInterface'))); + $this->httpAdapter = $httpAdapter = $this->createMock(AbstractHttpAdapter::class); + + $this->brainz = new MusicBrainz\MusicBrainz($httpAdapter, self::USERNAME, self::PASSWORD ); } /** @@ -41,4 +50,112 @@ public function testIsValidMBID($validation, $mbid) { $this->assertEquals($validation, $this->brainz->isValidMBID($mbid)); } + + public function testHttpOptions() + { + $applicationName = 'php-musibrainz'; + $version = '1.0.0'; + $contactInfo = 'development@oguzhanuysal.eu'; + + $this->brainz->setUserAgent($applicationName, $version, $contactInfo); + + $userAgent = $applicationName . '/' . $version . ' (' . $contactInfo . ')'; + + $httpOptionsExpect = [ + 'method' => 'GET', + 'user-agent' => $userAgent, + 'user' => self::USERNAME, + 'password' => self::PASSWORD + ]; + + $this->assertEquals($httpOptionsExpect, $this->brainz->getHttpOptions()); + $this->assertEquals($userAgent, $this->brainz->getUserAgent()); + } + + public function testGetSetters() + { + $this->assertEquals(self::USERNAME, $this->brainz->getUser()); + $this->assertEquals(self::PASSWORD, $this->brainz->getPassword()); + } + + /** + * @test + */ + public function willValidateFilter() + { + $this->assertTrue($this->brainz->validateFilter(['official'], MusicBrainz\MusicBrainz::$validReleaseStatuses)); + } + + /** + * @test + * @expectedException MusicBrainz\Exception + */ + public function willThrowExceptionIfFilterValidationFails() + { + $this->brainz->validateFilter(['Invalid'], MusicBrainz\MusicBrainz::$validReleaseTypes); + } + + /** + * @test + */ + public function willValidateInclude() + { + $includes = array( + 'releases', + 'recordings', + 'release-groups', + 'user-ratings' + ); + + $this->assertTrue($this->brainz->validateInclude($includes, MusicBrainz\MusicBrainz::$validIncludes['artist'])); + } + + /** + * @test + * @expectedException \OutOfBoundsException + */ + public function willThrowOutOfBoundsExceptionIfIncludeValidationFails() + { + $this->brainz->validateInclude(['out-of-bound'], MusicBrainz\MusicBrainz::$validIncludes['artist']); + } + + /** + * @test + * @expectedException MusicBRainz\Exception + */ + public function userAgentVersionCannotContainDash() + { + $this->brainz->setUserAgent('application', '1.0-beta', 'test'); + } + + public function testLookup() + { + $includes = array( + 'releases', + 'recordings', + 'release-groups', + 'user-ratings' + ); + + $this->httpAdapter->expects($this->once()) + ->method('call') + ->willReturn('{"secondary-type-ids":["dd2a21e1-0c00-3729-a7a0-de60b84eb5d1","0c60f497-ff81-3818-befd-abfc84a4858b"],"id":"e4307c5f-1959-4163-b4b1-ded4f9d786b0","title":"Born This Way: The Remix","secondary-types":["Compilation","Remix"],"disambiguation":"","first-release-date":"2011-11-18","primary-type-id":"f529b476-6e62-324f-b0aa-1f3e33d313fc","primary-type":"Album"}'); + + $this->brainz->lookup('artist', '4dbf5678-7a31-406a-abbe-232f8ac2cd63', $includes); + } + + public function testSearch() + { + $args = [ + 'artist' => 'Weezer' + ]; + + $this->httpAdapter->expects($this->once()) + ->method('call') + ->willReturn(get_object_vars(\GuzzleHttp\json_decode('{"created":"2017-04-22T00:34:45.859Z","count":89,"offset":0,"release-groups":[{"id":"37e08cb3-ef16-321a-a76c-efdb2f90d4bf","score":"100","count":1,"title":"Lion and the Witch \'redux\'","primary-type":"Single","secondary-types":["Live"],"artist-credit":[{"artist":{"id":"6fe07aa5-fec0-4eca-a456-f29bff451b04","name":"Weezer","sort-name":"Weezer"}}],"releases":[{"id":"15d527b3-f248-4b5f-bb01-7b3c78e20b7c","title":"Lion and the Witch \'redux\'","status":"Official"}]}]}'))); + + $releaseGroups = $this->brainz->search(new MusicBrainz\Filters\ReleaseGroupFilter($args)); + + $this->assertEquals(MusicBrainz\ReleaseGroup::class, get_class($releaseGroups[0])); + } }