Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions lib/Github/Api/AbstractApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
abstract class AbstractApi implements ApiInterface
{

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless line

/**
* The client
*
Expand All @@ -27,6 +28,7 @@ abstract class AbstractApi implements ApiInterface
protected $perPage;

/**
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again (and again for after)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why's this line been added?

* @param Client $client
*/
public function __construct(Client $client)
Expand All @@ -39,6 +41,7 @@ public function configure()
}

/**
*
* @return null|int
*/
public function getPerPage()
Expand All @@ -47,6 +50,7 @@ public function getPerPage()
}

/**
*
* @param null|int $perPage
*/
public function setPerPage($perPage)
Expand Down Expand Up @@ -77,6 +81,27 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr
return ResponseMediator::getContent($response);
}

/**
* Send a HEAD request with query parameters
*
* @param string $path Request path.
* @param array $parameters HEAD parameters.
* @param array $requestHeaders Request headers.
* @return \Guzzle\Http\Message\Response
*/
protected function head($path, array $parameters = array(), $requestHeaders = array())
{
if (array_key_exists('ref', $parameters) && is_null($parameters['ref'])) {
unset($parameters['ref']);
}

$response = $this->client->getHttpClient()->request($path, null, 'HEAD', $requestHeaders, array(
'query' => $parameters
));

return $response;
}

/**
* Send a POST request with JSON-encoded parameters.
*
Expand Down Expand Up @@ -112,7 +137,6 @@ protected function postRaw($path, $body, $requestHeaders = array())
return ResponseMediator::getContent($response);
}


/**
* Send a PATCH request with JSON-encoded parameters.
*
Expand All @@ -131,7 +155,6 @@ protected function patch($path, array $parameters = array(), $requestHeaders = a
return ResponseMediator::getContent($response);
}


/**
* Send a PUT request with JSON-encoded parameters.
*
Expand All @@ -150,7 +173,6 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr
return ResponseMediator::getContent($response);
}


/**
* Send a DELETE request with JSON-encoded parameters.
*
Expand All @@ -172,7 +194,7 @@ protected function delete($path, array $parameters = array(), $requestHeaders =
/**
* Create a JSON encoded version of an array of parameters.
*
* @param array $parameters Request parameters
* @param array $parameters Request parameters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nop

* @return null|string
*/
protected function createJsonBody(array $parameters)
Expand Down
37 changes: 37 additions & 0 deletions lib/Github/Api/Repository/Contents.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Github\Exception\InvalidArgumentException;
use Github\Exception\ErrorException;
use Github\Exception\MissingArgumentException;
use Github\Exception\TwoFactorAuthenticationRequiredException;

/**
* @link http://developer.github.com/v3/repos/contents/
Expand Down Expand Up @@ -92,6 +93,42 @@ public function create($username, $repository, $path, $content, $message, $branc
return $this->put($url, $parameters);
}

/**
* Checks that a given path exists in a repository.
*
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $path path of file to check
* @param null|string $reference reference to a branch or commit
* @return boolean
*/
public function exists($username, $repository, $path, $reference = null)
{
$url = 'repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents';

if (null !== $path) {
$url .= '/'.rawurlencode($path);
}

try {
$response = $this->head($url, array(
'ref' => $reference
));

if ($response->getStatusCode() != 200) {
return false;
}
}
catch (TwoFactorAuthenticationRequiredException $ex) {
throw $ex;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 1 line above with } catch, same for others

}
catch (\Exception $ex) {
return false;
}

return true;
}

/**
* Updates the contents of a file in a repository
* @link http://developer.github.com/v3/repos/contents/#update-a-file
Expand Down
78 changes: 78 additions & 0 deletions test/Github/Tests/Api/Repository/ContentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Github\Tests\Api\Repository;

use Github\Tests\Api\TestCase;
use Github\Exception\TwoFactorAuthenticationRequiredException;

class ContentsTest extends TestCase
{
Expand Down Expand Up @@ -38,6 +39,83 @@ public function shouldShowReadme()
$this->assertEquals($expectedValue, $api->readme('KnpLabs', 'php-github-api'));
}

/**
* @test
*/
public function shouldReturnTrueWhenFileExists()
{
$responseMock = $this->getMockBuilder('\Guzzle\Http\Message\Response')
->disableOriginalConstructor()
->getMock();

$responseMock->expects($this->any())
->method('getStatusCode')
->willReturn(200);

$api = $this->getApiMock();
$api->expects($this->once())
->method('head')
->with('repos/KnpLabs/php-github-api/contents/composer.json', array('ref' => null))
->will($this->returnValue($responseMock));

$this->assertEquals(true, $api->exists('KnpLabs', 'php-github-api', 'composer.json'));
}

private function getGuzzleResponseMock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we follow public -> protected -> private orderding

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm a " shortest vertical distance" fiend :) but fixed...

{
$responseMock = $this->getMockBuilder('\Guzzle\Http\Message\Response')
->disableOriginalConstructor()
->getMock();

return $responseMock;
}

public function getFailureStubsForExistsTest()
{
$nonOkResponseMock =$this->getGuzzleResponseMock();

$nonOkResponseMock->expects($this->any())
->method('getStatusCode')
->willReturn(403);

return array(
array($this->throwException(new \ErrorException())),
array($this->returnValue($nonOkResponseMock))
);
}

/**
* @test
* @dataProvider getFailureStubsForExistsTest
*/
public function shouldReturnFalseWhenFileIsNotFound(\PHPUnit_Framework_MockObject_Stub $failureStub)
{
$expectedValue = array('some-header' => 'value');

$api = $this->getApiMock();
$api->expects($this->once())
->method('head')
->with('repos/KnpLabs/php-github-api/contents/composer.json', array('ref' => null))
->will($failureStub);

$this->assertFalse($api->exists('KnpLabs', 'php-github-api', 'composer.json'));
}

/**
* @test
* @expectedException \Github\Exception\TwoFactorAuthenticationRequiredException
*/
public function shouldBubbleTwoFactorAuthenticationRequiredExceptionsWhenCheckingFileRequiringAuth()
{
$api = $this->getApiMock();
$api->expects($this->once())
->method('head')
->with('repos/KnpLabs/php-github-api/contents/composer.json', array('ref' => null))
->will($this->throwException(new TwoFactorAuthenticationRequiredException(0)));

$api->exists('KnpLabs', 'php-github-api', 'composer.json');
}

/**
* @test
*/
Expand Down
2 changes: 1 addition & 1 deletion test/Github/Tests/Api/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected function getApiMock()
$client->setHttpClient($mock);

return $this->getMockBuilder($this->getApiClass())
->setMethods(array('get', 'post', 'postRaw', 'patch', 'delete', 'put'))
->setMethods(array('get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'))
->setConstructorArgs(array($client))
->getMock();
}
Expand Down