diff --git a/src/Composer/Util/Bitbucket.php b/src/Composer/Util/Bitbucket.php index e27bd7439..24ba98f98 100644 --- a/src/Composer/Util/Bitbucket.php +++ b/src/Composer/Util/Bitbucket.php @@ -18,6 +18,7 @@ use Composer\Config; use Composer\Downloader\TransportException; /** + * I used GitHub.php as a template. * @author Paul Wenke */ class Bitbucket diff --git a/src/Composer/Util/StreamContextFactory.php b/src/Composer/Util/StreamContextFactory.php index ad1f3b956..426eb0273 100644 --- a/src/Composer/Util/StreamContextFactory.php +++ b/src/Composer/Util/StreamContextFactory.php @@ -129,7 +129,7 @@ final class StreamContextFactory $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']); } - if (isset($options['http']['content'])) { + if (isset($options['http']['content']) && (is_array($options['http']['content']) || is_object($options['http']['content']))) { $options['http']['content'] = http_build_query($options['http']['content']); } diff --git a/tests/Composer/Test/Util/BitbucketTest.php b/tests/Composer/Test/Util/BitbucketTest.php new file mode 100644 index 000000000..6decb5f74 --- /dev/null +++ b/tests/Composer/Test/Util/BitbucketTest.php @@ -0,0 +1,137 @@ + + * Jordi Boggiano + * + * 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\Util\Bitbucket; + +/** + * I used GitHubTest.php as a template. + * @author Paul Wenke + */ +class BitbucketTest extends \PHPUnit_Framework_TestCase +{ + private $username = 'username'; + private $password = 'password'; + private $authcode = 'authcode'; + private $message = 'mymessage'; + private $origin = 'bitbucket.org'; + private $token = 'bitbuckettoken'; + + public function testUsernamePasswordAuthenticationFlow() + { + $io = $this->getIOMock(); + $io + ->expects($this->at(0)) + ->method('writeError') + ->with($this->message) + ; + + $io->expects($this->exactly(2)) + ->method('askAndHideAnswer') + ->withConsecutive( + array('Consumer Key (hidden): '), + array('Consumer Secret (hidden): ') + ) + ->willReturnOnConsecutiveCalls($this->username, $this->password); + + $rfs = $this->getRemoteFilesystemMock(); + $rfs + ->expects($this->once()) + ->method('getContents') + ->with( + $this->equalTo($this->origin), + $this->equalTo(sprintf('https://%s/site/oauth2/access_token', $this->origin)), + $this->isFalse(), + $this->anything() + ) + ->willReturn(sprintf('{}', $this->token)) + ; + + $config = $this->getConfigMock(); + $config + ->expects($this->exactly(2)) + ->method('getAuthConfigSource') + ->willReturn($this->getAuthJsonMock()) + ; + $config + ->expects($this->once()) + ->method('getConfigSource') + ->willReturn($this->getConfJsonMock()) + ; + + $bitbucket = new Bitbucket($io, $config, null, $rfs); + + $this->assertTrue($bitbucket->authorizeOAuthInteractively($this->origin, $this->message)); + } + + private function getIOMock() + { + $io = $this + ->getMockBuilder('Composer\IO\ConsoleIO') + ->disableOriginalConstructor() + ->getMock() + ; + + return $io; + } + + private function getConfigMock() + { + $config = $this->getMock('Composer\Config'); + + return $config; + } + + private function getRemoteFilesystemMock() + { + $rfs = $this + ->getMockBuilder('Composer\Util\RemoteFilesystem') + ->disableOriginalConstructor() + ->getMock() + ; + + return $rfs; + } + + private function getAuthJsonMock() + { + $authjson = $this + ->getMockBuilder('Composer\Config\JsonConfigSource') + ->disableOriginalConstructor() + ->getMock() + ; + $authjson + ->expects($this->atLeastOnce()) + ->method('getName') + ->willReturn('auth.json') + ; + + return $authjson; + } + + private function getConfJsonMock() + { + $confjson = $this + ->getMockBuilder('Composer\Config\JsonConfigSource') + ->disableOriginalConstructor() + ->getMock() + ; + $confjson + ->expects($this->atLeastOnce()) + ->method('removeConfigSetting') + ->with('bitbucket-oauth.'.$this->origin) + ; + + return $confjson; + } +}