<?php
/**
 *
 * @group wporg-plugin-api
 */
class Tests_Wporg_Plugin_API extends WP_UnitTestCase {

	public function setUp() {
		parent::setup();
	}

	function test_wp_org_plugin_api_serialize_php() {
		$args = (object) array( 'slug' => 'hello-dolly' );
		$request = array( 'action' => 'plugin_information', 'timeout' => 15, 'request' => serialize( $args) );
		$url = 'http://api.wordpress.org/plugins/info/1.0/';
		$response = wp_remote_post( $url, array( 'body' => $request ) );
		$plugin_info = unserialize( $response['body'] );

		$this->assertObjectHasAttribute( 'name',  	$plugin_info, 	'Name exists' );
		$this->assertObjectHasAttribute( 'slug',  	$plugin_info, 	'Slug exits' );
		$this->assertObjectHasAttribute( 'version', $plugin_info, 	'Version exists' );
		$this->assertObjectHasAttribute( 'author',  $plugin_info, 	'Author exists' );
		$this->assertObjectHasAttribute( 'author_profile',  $plugin_info, 'Author Profile exists' );
		$this->assertObjectHasAttribute( 'contributors', $plugin_info, 'Contributors exists' );
		$this->assertTrue( is_array( $plugin_info->contributors ), 	'Contributors should be an array');
		$this->assertObjectHasAttribute( 'requires',$plugin_info, 'Requires exists' );
		$this->assertObjectHasAttribute( 'tested',  $plugin_info, 	'Tested exists' );
		$this->assertObjectHasAttribute( 'compatibility',  $plugin_info, 'Compatibility exists' );
		$this->assertTrue( is_array( $plugin_info->compatibility ), 'Compatibility should be an array'  );

		// Ratings
		$this->assertObjectHasAttribute( 'ratings',  $plugin_info, 'Ratings exists' );
		$this->assertTrue( is_array( $plugin_info->ratings ), 	'Ratings should be an array' );
		$this->assertArrayHasKey( '1',  $plugin_info->ratings, 	'Rating should have an attribute of 1' );
		$this->assertArrayHasKey( '2',  $plugin_info->ratings, 	'Rating should have an attribute of 2' );
		$this->assertArrayHasKey( '3',  $plugin_info->ratings, 	'Rating should have an attribute of 3' );
		$this->assertArrayHasKey( '4',  $plugin_info->ratings, 	'Rating should have an attribute of 4' );
		$this->assertArrayHasKey( '5',  $plugin_info->ratings, 	'Rating should have an attribute of 5' );
		$this->assertObjectHasAttribute( 'num_ratings',  $plugin_info, 'Num ratings exists'  );
		$this->assertTrue( is_numeric( $plugin_info->num_ratings ) );

		// Downloaded
		$this->assertObjectHasAttribute( 'downloaded',  $plugin_info, 'Downloaded exists' );
		$this->assertTrue( is_numeric( $plugin_info->downloaded ) );

		$this->assertObjectHasAttribute( 'last_updated',  $plugin_info, 'last_updated exists'  );
		$this->assertObjectHasAttribute( 'added',  $plugin_info, 	'Added exists'  );
		$this->assertObjectHasAttribute( 'homepage',  $plugin_info, 'Homepage exists' );
		$this->assertObjectHasAttribute( 'sections',  $plugin_info, 'Sections Exists' );
		$this->assertTrue( is_array( $plugin_info->sections ), 'Sections should be an array' );

		// Download link
		$this->assertObjectHasAttribute( 'download_link',  $plugin_info, 'Download Link exists' );
		$download_url_parsed = parse_url( $plugin_info->download_link );
		$this->assertEquals( $download_url_parsed['host'], 'downloads.wordpress.org' );
		$this->assertStringEndsWith( $plugin_info->slug . '.' . $plugin_info->version . '.zip', $download_url_parsed['path'] , 'Download URL contains plugin slug and version' );

		// Donate link
		$this->assertObjectHasAttribute( 'donate_link',  $plugin_info, 'Donate link exists' );

		// Tags should be key
		$this->assertObjectHasAttribute( 'tags',  $plugin_info, 'Tags exists' );
		$this->assertTrue( is_array( $plugin_info->tags ), 'Tags should be an array' );
	}

	function test_wp_org_plugin_api_serialize_php_get() {
		$url = 'http://api.wordpress.org/plugins/info/1.0/hello-dolly';
		$response = wp_remote_get( $url );
		$plugin_info = unserialize( $response['body'] );

		$this->assertObjectHasAttribute( 'name',  	$plugin_info, 	'Name exists' );
		$this->assertObjectHasAttribute( 'slug',  	$plugin_info, 	'Slug exits' );
		$this->assertObjectHasAttribute( 'version', $plugin_info, 	'Version exists' );
		$this->assertObjectHasAttribute( 'author',  $plugin_info, 	'Author exists' );
		$this->assertObjectHasAttribute( 'author_profile',  $plugin_info, 'Author Profile exists' );
		$this->assertObjectHasAttribute( 'contributors', $plugin_info, 'Contributors exists' );
		$this->assertTrue( is_array( $plugin_info->contributors ), 	'Contributors should be an array');
		$this->assertObjectHasAttribute( 'requires',$plugin_info, 'Requires exists' );
		$this->assertObjectHasAttribute( 'tested',  $plugin_info, 	'Tested exists' );
		$this->assertObjectHasAttribute( 'compatibility',  $plugin_info, 'Compatibility exists' );
		$this->assertTrue( is_array( $plugin_info->compatibility ), 'Compatibility should be an array'  );

		// Ratings
		$this->assertObjectHasAttribute( 'ratings',  $plugin_info, 'Ratings exists' );
		$this->assertTrue( is_array( $plugin_info->ratings ), 	'Ratings should be an array' );
		$this->assertArrayHasKey( '1',  $plugin_info->ratings, 	'Rating should have an attribute of 1' );
		$this->assertArrayHasKey( '2',  $plugin_info->ratings, 	'Rating should have an attribute of 2' );
		$this->assertArrayHasKey( '3',  $plugin_info->ratings, 	'Rating should have an attribute of 3' );
		$this->assertArrayHasKey( '4',  $plugin_info->ratings, 	'Rating should have an attribute of 4' );
		$this->assertArrayHasKey( '5',  $plugin_info->ratings, 	'Rating should have an attribute of 5' );
		$this->assertObjectHasAttribute( 'num_ratings',  $plugin_info, 'Num ratings exists'  );
		$this->assertTrue( is_numeric( $plugin_info->num_ratings ) );

		// Downloaded
		$this->assertObjectHasAttribute( 'downloaded',  $plugin_info, 'Downloaded exists' );
		$this->assertTrue( is_numeric( $plugin_info->downloaded ) );

		$this->assertObjectHasAttribute( 'last_updated',  $plugin_info, 'last_updated exists'  );
		$this->assertObjectHasAttribute( 'added',  $plugin_info, 	'Added exists'  );
		$this->assertObjectHasAttribute( 'homepage',  $plugin_info, 'Homepage exists' );
		$this->assertObjectHasAttribute( 'sections',  $plugin_info, 'Sections Exists' );
		$this->assertTrue( is_array( $plugin_info->sections ), 'Sections should be an array' );

		// Download link
		$this->assertObjectHasAttribute( 'download_link',  $plugin_info, 'Download Link exists' );
		$download_url_parsed = parse_url( $plugin_info->download_link );
		$this->assertEquals( $download_url_parsed['host'], 'downloads.wordpress.org' );
		$this->assertStringEndsWith( $plugin_info->slug . '.' . $plugin_info->version . '.zip', $download_url_parsed['path'] , 'Download URL contains plugin slug and version' );

		// Donate link
		$this->assertObjectHasAttribute( 'donate_link',  $plugin_info, 'Donate link exists' );

		// Tags should be key
		$this->assertObjectHasAttribute( 'tags',  $plugin_info, 'Tags exists' );
		$this->assertTrue( is_array( $plugin_info->tags ), 'Tags should be an array' );
	}

	function test_wp_org_plugin_api_json() {
		$url = 'http://api.wordpress.org/plugins/info/1.0/hello-dolly.json';
		$response = wp_remote_get( $url );
		$plugin_info = json_decode( $response['body'] );

		$this->assertObjectHasAttribute( 'name',  	$plugin_info, 	'Name exists' );
		$this->assertObjectHasAttribute( 'slug',  	$plugin_info, 	'Slug exits' );
		$this->assertObjectHasAttribute( 'version', $plugin_info, 	'Version exists' );
		$this->assertObjectHasAttribute( 'author',  $plugin_info, 	'Author exists' );
		$this->assertObjectHasAttribute( 'author_profile',  $plugin_info, 'Author Profile exists' );
		$this->assertObjectHasAttribute( 'contributors', $plugin_info, 'Contributors exists' );
		$this->assertTrue( is_object( $plugin_info->contributors ), 	'Contributors should be an object');
		$this->assertObjectHasAttribute( 'requires',$plugin_info, 'Requires exists' );
		$this->assertObjectHasAttribute( 'tested',  $plugin_info, 	'Tested exists' );
		$this->assertObjectHasAttribute( 'compatibility', $plugin_info, 'Compatibility exists' );
		$this->assertTrue( is_array( $plugin_info->compatibility ), 'Compatibility should be an object'  );

		// Ratings
		$this->assertObjectHasAttribute( 'ratings',  $plugin_info, 'Ratings exists' );
		$this->assertTrue( is_object( $plugin_info->ratings ), 	'Ratings should be an object' );

		// Num Ratings
		$this->assertObjectHasAttribute( 'num_ratings',  $plugin_info, 'Num ratings exists'  );
		$this->assertTrue( is_numeric( $plugin_info->num_ratings ) );

		// Downloaded
		$this->assertObjectHasAttribute( 'downloaded',  $plugin_info, 'Downloaded exists' );
		$this->assertTrue( is_numeric( $plugin_info->downloaded ) );

		$this->assertObjectHasAttribute( 'last_updated',  $plugin_info, 'last_updated exists'  );
		$this->assertObjectHasAttribute( 'added',  $plugin_info, 	'Added exists'  );
		$this->assertObjectHasAttribute( 'homepage',  $plugin_info, 'Homepage exists' );
		$this->assertObjectHasAttribute( 'sections',  $plugin_info, 'Sections Exists' );
		$this->assertTrue( is_object( $plugin_info->sections ), 'Sections should be an object' );

		// Download link
		$this->assertObjectHasAttribute( 'download_link',  $plugin_info, 'Download Link exists' );
		$download_url_parsed = parse_url( $plugin_info->download_link );
		$this->assertEquals( $download_url_parsed['host'], 'downloads.wordpress.org' );
		$this->assertStringEndsWith( $plugin_info->slug . '.' . $plugin_info->version . '.zip', $download_url_parsed['path'] , 'Download URL contains plugin slug and version' );

		// Donate link
		$this->assertObjectHasAttribute( 'donate_link',  $plugin_info, 'Donate link exists' );

		$this->assertObjectHasAttribute( 'short_description',  $plugin_info, 'Short Description exists' );

		// Tags should be key
		$this->assertObjectHasAttribute( 'tags',  $plugin_info, 'Tags exists' );
		$this->assertTrue( is_array( $plugin_info->tags ), 'Tags should be an array' );
	}
}
