1
0
Fork 0

Add Util\AuthHelper unit test coverage (#8863)

* Add AuthHelper::addAuthenticationHeader() test on missing authentication credentials.

* Add AuthHelper::addAuthenticationHeader() test on bearer password.

* Add AuthHelper::addAuthenticationHeader() test on Github token.

* Add AuthHelper::addAuthenticationHeader() test on Gitlab Oauth token.

* Add $authenticationDisplayMessage write expectation to AuthHelper::addAuthenticationHeader() tests.

* Add AuthHelper::addAuthenticationHeader() test on Gitlab private token.

* Add AuthHelper::addAuthenticationHeader() test on Bitbucket Oauth token.

* Add AuthHelper::addAuthenticationHeader() test on Bitbucket public urls.

* Add AuthHelper::addAuthenticationHeader() test on Basic Http Authentication.

* Add AuthHelper::isPublicBitBucketDownload() tests.

* Rename AuthHelperTest $credentials variable to $auth.

* Add AuthHelper::storeAuth() test for auto-store option.

* Add AuthHelper::storeAuth() test for user prompt and y(es) answer.

* Add AuthHelper::storeAuth() test for user prompt and n(o) answer.

* Add AuthHelper::storeAuth() test for user prompt with invalid answer.

* Add AuthHelper::promptAuthIfNeeded() test for Github authentication failure.

- add GitHub hard dependency mock (new GitHub(...) mock)

* Run AuthHelper::promptAuthIfNeeded() tests only with PHP > 5.3

* Run AuthHelper::promptAuthIfNeeded() tests only with PHP >= 5.4

* Run AuthHelper::promptAuthIfNeeded() tests only with PHP 5.4

* Exclude PHPStan analyses of '../tests/Composer/Test/Util/Mocks/*'

* Exclude AuthHelper::promptAuthIfNeeded() tests from current pull request.

* Extract repetitive AuthHelperTest authentication expectation into a method.
pull/8869/head
Michael Chekin 2020-05-04 09:48:23 +02:00 committed by GitHub
parent c39391323d
commit c23670c3ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 525 additions and 0 deletions

View File

@ -0,0 +1,525 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Test\Util;
use Composer\IO\IOInterface;
use Composer\Test\TestCase;
use Composer\Util\AuthHelper;
use Composer\Util\Bitbucket;
use RuntimeException;
/**
* @author Michael Chekin <mchekin@gmail.com>
*/
class AuthHelperTest extends TestCase
{
/** @type \Composer\IO\IOInterface|\PHPUnit_Framework_MockObject_MockObject */
private $io;
/** @type \Composer\Config|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @type AuthHelper */
private $authHelper;
protected function setUp()
{
$this->io = $this
->getMockBuilder('Composer\IO\IOInterface')
->disableOriginalConstructor()
->getMock();
$this->config = $this->getMockBuilder('Composer\Config')->getMock();
$this->authHelper = new AuthHelper($this->io, $this->config);
}
public function testAddAuthenticationHeaderWithoutAuthCredentials()
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'http://example.org';
$url = 'file://' . __FILE__;
$this->io->expects($this->once())
->method('hasAuthentication')
->with($origin)
->willReturn(false);
$this->assertSame(
$headers,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function testAddAuthenticationHeaderWithBearerPassword()
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'http://example.org';
$url = 'file://' . __FILE__;
$auth = array(
'username' => 'my_username',
'password' => 'bearer'
);
$this->expectsAuthentication($origin, $auth);
$expectedHeaders = array_merge($headers, array('Authorization: Bearer ' . $auth['username']));
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function testAddAuthenticationHeaderWithGithubToken()
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'github.com';
$url = 'https://api.github.com/';
$auth = array(
'username' => 'my_username',
'password' => 'x-oauth-basic'
);
$this->expectsAuthentication($origin, $auth);
$this->io->expects($this->once())
->method('writeError')
->with('Using GitHub token authentication', true, IOInterface::DEBUG);
$expectedHeaders = array_merge($headers, array('Authorization: token ' . $auth['username']));
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function testAddAuthenticationHeaderWithGitlabOathToken()
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'gitlab.com';
$url = 'https://api.gitlab.com/';
$auth = array(
'username' => 'my_username',
'password' => 'oauth2'
);
$this->expectsAuthentication($origin, $auth);
$this->config->expects($this->once())
->method('get')
->with('gitlab-domains')
->willReturn(array($origin));
$this->io->expects($this->once())
->method('writeError')
->with('Using GitLab OAuth token authentication', true, IOInterface::DEBUG);
$expectedHeaders = array_merge($headers, array('Authorization: Bearer ' . $auth['username']));
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function gitlabPrivateTokenProvider()
{
return array(
array('private-token'),
array('gitlab-ci-token'),
);
}
/**
* @dataProvider gitlabPrivateTokenProvider
*
* @param string $password
*/
public function testAddAuthenticationHeaderWithGitlabPrivateToken($password)
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'gitlab.com';
$url = 'https://api.gitlab.com/';
$auth = array(
'username' => 'my_username',
'password' => $password
);
$this->expectsAuthentication($origin, $auth);
$this->config->expects($this->once())
->method('get')
->with('gitlab-domains')
->willReturn(array($origin));
$this->io->expects($this->once())
->method('writeError')
->with('Using GitLab private token authentication', true, IOInterface::DEBUG);
$expectedHeaders = array_merge($headers, array('PRIVATE-TOKEN: ' . $auth['username']));
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function testAddAuthenticationHeaderWithBitbucketOathToken()
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'bitbucket.org';
$url = 'https://bitbucket.org/site/oauth2/authorize';
$auth = array(
'username' => 'x-token-auth',
'password' => 'my_password'
);
$this->expectsAuthentication($origin, $auth);
$this->config->expects($this->once())
->method('get')
->with('gitlab-domains')
->willReturn(array());
$this->io->expects($this->once())
->method('writeError')
->with('Using Bitbucket OAuth token authentication', true, IOInterface::DEBUG);
$expectedHeaders = array_merge($headers, array('Authorization: Bearer ' . $auth['password']));
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function bitbucketPublicUrlProvider()
{
return array(
array('https://bitbucket.org/user/repo/downloads/whatever'),
array('https://bbuseruploads.s3.amazonaws.com/9421ee72-638e-43a9-82ea-39cfaae2bfaa/downloads/b87c59d9-54f3-4922-b711-d89059ec3bcf'),
);
}
/**
* @dataProvider bitbucketPublicUrlProvider
*
* @param string $url
*/
public function testAddAuthenticationHeaderWithBitbucketPublicUrl($url)
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$origin = 'bitbucket.org';
$auth = array(
'username' => 'x-token-auth',
'password' => 'my_password'
);
$this->expectsAuthentication($origin, $auth);
$this->config->expects($this->once())
->method('get')
->with('gitlab-domains')
->willReturn(array());
$this->assertSame(
$headers,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
public function basicHttpAuthenticationProvider()
{
return array(
array(
Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
'bitbucket.org',
array(
'username' => 'x-token-auth',
'password' => 'my_password'
)
),
array(
'https://some-api.url.com',
'some-api.url.com',
array(
'username' => 'my_username',
'password' => 'my_password'
)
),
);
}
/**
* @dataProvider basicHttpAuthenticationProvider
*
* @param string $url
* @param string $origin
* @param array $auth
*/
public function testAddAuthenticationHeaderWithBasicHttpAuthentication($url, $origin, $auth)
{
$headers = array(
'Accept-Encoding: gzip',
'Connection: close'
);
$this->expectsAuthentication($origin, $auth);
$this->config->expects($this->once())
->method('get')
->with('gitlab-domains')
->willReturn(array());
$this->io->expects($this->once())
->method('writeError')
->with(
'Using HTTP basic authentication with username "' . $auth['username'] . '"',
true,
IOInterface::DEBUG
);
$expectedHeaders = array_merge(
$headers,
array('Authorization: Basic ' . base64_encode($auth['username'] . ':' . $auth['password']))
);
$this->assertSame(
$expectedHeaders,
$this->authHelper->addAuthenticationHeader($headers, $origin, $url)
);
}
/**
* @dataProvider bitbucketPublicUrlProvider
*
* @param string $url
*/
public function testIsPublicBitBucketDownloadWithBitbucketPublicUrl($url)
{
$this->assertTrue($this->authHelper->isPublicBitBucketDownload($url));
}
public function testIsPublicBitBucketDownloadWithNonBitbucketPublicUrl()
{
$this->assertFalse($this->authHelper->isPublicBitBucketDownload(
'https://bitbucket.org/site/oauth2/authorize')
);
}
public function testStoreAuthAutomatically()
{
$origin = 'github.com';
$storeAuth = true;
$auth = array(
'username' => 'my_username',
'password' => 'my_password'
);
/** @var \Composer\Config\ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject $configSource */
$configSource = $this
->getMockBuilder('Composer\Config\ConfigSourceInterface')
->disableOriginalConstructor()
->getMock();
$this->config->expects($this->once())
->method('getAuthConfigSource')
->willReturn($configSource);
$this->io->expects($this->once())
->method('getAuthentication')
->with($origin)
->willReturn($auth);
$configSource->expects($this->once())
->method('addConfigSetting')
->with('http-basic.'.$origin, $auth)
->willReturn($configSource);
$this->authHelper->storeAuth($origin, $storeAuth);
}
public function testStoreAuthWithPromptYesAnswer()
{
$origin = 'github.com';
$storeAuth = 'prompt';
$auth = array(
'username' => 'my_username',
'password' => 'my_password'
);
$answer = 'y';
$configSourceName = 'https://api.gitlab.com/source';
/** @var \Composer\Config\ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject $configSource */
$configSource = $this
->getMockBuilder('Composer\Config\ConfigSourceInterface')
->disableOriginalConstructor()
->getMock();
$this->config->expects($this->once())
->method('getAuthConfigSource')
->willReturn($configSource);
$configSource->expects($this->once())
->method('getName')
->willReturn($configSourceName);
$this->io->expects($this->once())
->method('askAndValidate')
->with(
'Do you want to store credentials for '.$origin.' in '.$configSourceName.' ? [Yn] ',
$this->anything(),
null,
'y'
)
->willReturnCallback(function ($question, $validator, $attempts, $default) use ($answer) {
$validator($answer);
return $answer;
});
$this->io->expects($this->once())
->method('getAuthentication')
->with($origin)
->willReturn($auth);
$configSource->expects($this->once())
->method('addConfigSetting')
->with('http-basic.'.$origin, $auth)
->willReturn($configSource);
$this->authHelper->storeAuth($origin, $storeAuth);
}
public function testStoreAuthWithPromptNoAnswer()
{
$origin = 'github.com';
$storeAuth = 'prompt';
$answer = 'n';
$configSourceName = 'https://api.gitlab.com/source';
/** @var \Composer\Config\ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject $configSource */
$configSource = $this
->getMockBuilder('Composer\Config\ConfigSourceInterface')
->disableOriginalConstructor()
->getMock();
$this->config->expects($this->once())
->method('getAuthConfigSource')
->willReturn($configSource);
$configSource->expects($this->once())
->method('getName')
->willReturn($configSourceName);
$this->io->expects($this->once())
->method('askAndValidate')
->with(
'Do you want to store credentials for '.$origin.' in '.$configSourceName.' ? [Yn] ',
$this->anything(),
null,
'y'
)
->willReturnCallback(function ($question, $validator, $attempts, $default) use ($answer) {
$validator($answer);
return $answer;
});
$this->authHelper->storeAuth($origin, $storeAuth);
}
/**
* @expectedException RuntimeException
*/
public function testStoreAuthWithPromptInvalidAnswer()
{
$origin = 'github.com';
$storeAuth = 'prompt';
$answer = 'invalid';
$configSourceName = 'https://api.gitlab.com/source';
/** @var \Composer\Config\ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject $configSource */
$configSource = $this
->getMockBuilder('Composer\Config\ConfigSourceInterface')
->disableOriginalConstructor()
->getMock();
$this->config->expects($this->once())
->method('getAuthConfigSource')
->willReturn($configSource);
$configSource->expects($this->once())
->method('getName')
->willReturn($configSourceName);
$this->io->expects($this->once())
->method('askAndValidate')
->with(
'Do you want to store credentials for '.$origin.' in '.$configSourceName.' ? [Yn] ',
$this->anything(),
null,
'y'
)
->willReturnCallback(function ($question, $validator, $attempts, $default) use ($answer) {
$validator($answer);
return $answer;
});
$this->authHelper->storeAuth($origin, $storeAuth);
}
/**
* @param $origin
* @param $auth
*/
private function expectsAuthentication($origin, $auth)
{
$this->io->expects($this->once())
->method('hasAuthentication')
->with($origin)
->willReturn(true);
$this->io->expects($this->once())
->method('getAuthentication')
->with($origin)
->willReturn($auth);
}
}