Minor fixes and updated the rest of the code/tests to use HttpDownloader

main
Jordi Boggiano 6 years ago
parent 56805ecafe
commit 713bc4de1d

@ -176,8 +176,8 @@ class AwsPlugin implements PluginInterface, EventSubscriberInterface
if ($protocol === 's3') { if ($protocol === 's3') {
$awsClient = new AwsClient($this->io, $this->composer->getConfig()); $awsClient = new AwsClient($this->io, $this->composer->getConfig());
$s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient); $s3Downloader = new S3Downloader($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
$event->setRemoteFilesystem($s3RemoteFilesystem); $event->setHttpdownloader($s3Downloader);
} }
} }
} }

@ -104,7 +104,7 @@ EOT
$archiveManager = $composer->getArchiveManager(); $archiveManager = $composer->getArchiveManager();
} else { } else {
$factory = new Factory; $factory = new Factory;
$downloadManager = $factory->createDownloadManager($io, $config); $downloadManager = $factory->createDownloadManager($io, $config, $factory->createHttpDownloader($io, $config));
$archiveManager = $factory->createArchiveManager($config, $downloadManager); $archiveManager = $factory->createArchiveManager($config, $downloadManager);
} }

@ -51,12 +51,12 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
* *
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param Config $config The config * @param Config $config The config
* @param HttpDownloader $httpDownloader The remote filesystem
* @param EventDispatcher $eventDispatcher The event dispatcher * @param EventDispatcher $eventDispatcher The event dispatcher
* @param Cache $cache Cache instance * @param Cache $cache Cache instance
* @param HttpDownloader $httpDownloader The remote filesystem
* @param Filesystem $filesystem The filesystem * @param Filesystem $filesystem The filesystem
*/ */
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, Cache $cache, HttpDownloader $httpDownloader, Filesystem $filesystem = null) public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, Filesystem $filesystem = null)
{ {
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;

@ -30,10 +30,10 @@ class GzipDownloader extends ArchiveDownloader
{ {
protected $process; protected $process;
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
{ {
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
} }
protected function extract($file, $path) protected function extract($file, $path)

@ -33,10 +33,10 @@ class RarDownloader extends ArchiveDownloader
{ {
protected $process; protected $process;
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
{ {
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
} }
protected function extract($file, $path) protected function extract($file, $path)

@ -30,11 +30,11 @@ class XzDownloader extends ArchiveDownloader
{ {
protected $process; protected $process;
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
{ {
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
} }
protected function extract($file, $path) protected function extract($file, $path)

@ -36,10 +36,10 @@ class ZipDownloader extends ArchiveDownloader
protected $process; protected $process;
private $zipArchiveObject; private $zipArchiveObject;
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null) public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
{ {
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
parent::__construct($io, $config, $eventDispatcher, $cache, $downloader); parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
} }
/** /**

@ -325,14 +325,14 @@ class Factory
$io->loadConfiguration($config); $io->loadConfiguration($config);
} }
$rfs = self::createHttpDownloader($io, $config); $httpDownloader = self::createHttpDownloader($io, $config);
// initialize event dispatcher // initialize event dispatcher
$dispatcher = new EventDispatcher($composer, $io); $dispatcher = new EventDispatcher($composer, $io);
$composer->setEventDispatcher($dispatcher); $composer->setEventDispatcher($dispatcher);
// initialize repository manager // initialize repository manager
$rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs); $rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher);
$composer->setRepositoryManager($rm); $composer->setRepositoryManager($rm);
// load local repository // load local repository
@ -357,7 +357,7 @@ class Factory
if ($fullLoad) { if ($fullLoad) {
// initialize download manager // initialize download manager
$dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs); $dm = $this->createDownloadManager($io, $config, $httpDownloader, $dispatcher);
$composer->setDownloadManager($dm); $composer->setDownloadManager($dm);
// initialize autoload generator // initialize autoload generator
@ -451,7 +451,7 @@ class Factory
* @param EventDispatcher $eventDispatcher * @param EventDispatcher $eventDispatcher
* @return Downloader\DownloadManager * @return Downloader\DownloadManager
*/ */
public function createDownloadManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
{ {
$cache = null; $cache = null;
if ($config->get('cache-files-ttl') > 0) { if ($config->get('cache-files-ttl') > 0) {
@ -484,14 +484,14 @@ class Factory
$dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $executor, $fs)); $dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $executor, $fs));
$dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $executor, $fs)); $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $executor, $fs));
$dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config)); $dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config));
$dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
$dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
$dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $eventDispatcher, $cache, $rfs)); $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
$dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
$dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs)); $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
$dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache, $rfs)); $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
$dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache, $rfs)); $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
$dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $eventDispatcher, $cache, $rfs)); $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
return $dm; return $dm;
} }
@ -501,14 +501,8 @@ class Factory
* @param Downloader\DownloadManager $dm Manager use to download sources * @param Downloader\DownloadManager $dm Manager use to download sources
* @return Archiver\ArchiveManager * @return Archiver\ArchiveManager
*/ */
public function createArchiveManager(Config $config, Downloader\DownloadManager $dm = null) public function createArchiveManager(Config $config, Downloader\DownloadManager $dm)
{ {
if (null === $dm) {
$io = new IO\NullIO();
$io->loadConfiguration($config);
$dm = $this->createDownloadManager($io, $config);
}
$am = new Archiver\ArchiveManager($dm); $am = new Archiver\ArchiveManager($dm);
$am->addArchiver(new Archiver\ZipArchiver); $am->addArchiver(new Archiver\ZipArchiver);
$am->addArchiver(new Archiver\PharArchiver); $am->addArchiver(new Archiver\PharArchiver);

@ -18,7 +18,6 @@ use Composer\Package\Link;
use Composer\Package\RootAliasPackage; use Composer\Package\RootAliasPackage;
use Composer\Package\RootPackageInterface; use Composer\Package\RootPackageInterface;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Composer\Semver\VersionParser as SemverVersionParser;
/** /**
* @author Konstantin Kudryashiv <ever.zet@gmail.com> * @author Konstantin Kudryashiv <ever.zet@gmail.com>
@ -29,7 +28,7 @@ class ArrayLoader implements LoaderInterface
protected $versionParser; protected $versionParser;
protected $loadOptions; protected $loadOptions;
public function __construct(SemverVersionParser $parser = null, $loadOptions = false) public function __construct(VersionParser $parser = null, $loadOptions = false)
{ {
if (!$parser) { if (!$parser) {
$parser = new VersionParser; $parser = new VersionParser;

@ -102,7 +102,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->versionParser = new VersionParser(); $this->versionParser = new VersionParser();
$this->loader = new ArrayLoader($this->versionParser); $this->loader = new ArrayLoader($this->versionParser);
if ($httpDownloader && $this->options) { if ($httpDownloader && $this->options) {
// TODO solve this somehow - should be sent a request time not on the instance // TODO solve this somehow - should be sent at request time not on the instance
$httpDownloader = clone $httpDownloader; $httpDownloader = clone $httpDownloader;
$httpDownloader->setOptions($this->options); $httpDownloader->setOptions($this->options);
} }
@ -543,6 +543,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$response = $contents; $response = $contents;
} }
if (!isset($response['packages'][$name])) {
return;
}
$uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time'); $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time');
foreach ($response['packages'][$name] as $version) { foreach ($response['packages'][$name] as $version) {
if (isset($version['versions'])) { if (isset($version['versions'])) {
@ -566,6 +570,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}, function ($e) { }, function ($e) {
// TODO use ->done() above instead with react/promise 2.0 // TODO use ->done() above instead with react/promise 2.0
var_dump('Uncaught Ex', $e->getMessage()); var_dump('Uncaught Ex', $e->getMessage());
throw $e;
}); });
} }
} }
@ -644,6 +649,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->hasProviders = true; $this->hasProviders = true;
} }
// TODO this is for testing only, remove once packagist reports v2 protocol support
if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url)) {
$this->repoConfig['force-lazy-providers'] = true;
}
// force values for packagist // force values for packagist
if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) { if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) {
$this->url = 'https://repo.packagist.org'; $this->url = 'https://repo.packagist.org';
@ -927,6 +937,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$degradedMode =& $this->degradedMode; $degradedMode =& $this->degradedMode;
$accept = function ($response) use ($io, $url, $cache, $cacheKey) { $accept = function ($response) use ($io, $url, $cache, $cacheKey) {
// package not found is acceptable for a v2 protocol repository
if ($response->getStatusCode() === 404) {
return array('packages' => array());
}
$json = $response->getBody(); $json = $response->getBody();
if ($json === '' && $response->getStatusCode() === 304) { if ($json === '' && $response->getStatusCode() === 304) {
return true; return true;

@ -12,7 +12,7 @@
namespace Composer\Repository\Pear; namespace Composer\Repository\Pear;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
/** /**
* Base PEAR Channel reader. * Base PEAR Channel reader.
@ -33,12 +33,12 @@ abstract class BaseChannelReader
const ALL_RELEASES_NS = 'http://pear.php.net/dtd/rest.allreleases'; const ALL_RELEASES_NS = 'http://pear.php.net/dtd/rest.allreleases';
const PACKAGE_INFO_NS = 'http://pear.php.net/dtd/rest.package'; const PACKAGE_INFO_NS = 'http://pear.php.net/dtd/rest.package';
/** @var RemoteFilesystem */ /** @var HttpDownloader */
private $rfs; private $httpDownloader;
protected function __construct(RemoteFilesystem $rfs) protected function __construct(HttpDownloader $httpDownloader)
{ {
$this->rfs = $rfs; $this->httpDownloader = $httpDownloader;
} }
/** /**
@ -52,7 +52,11 @@ abstract class BaseChannelReader
protected function requestContent($origin, $path) protected function requestContent($origin, $path)
{ {
$url = rtrim($origin, '/') . '/' . ltrim($path, '/'); $url = rtrim($origin, '/') . '/' . ltrim($path, '/');
$content = $this->rfs->getContents($origin, $url, false); try {
$content = $this->httpDownloader->get($url)->getBody();
} catch (\Exception $e) {
throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.', 0, $e);
}
if (!$content) { if (!$content) {
throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.'); throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.');
} }

@ -12,7 +12,7 @@
namespace Composer\Repository\Pear; namespace Composer\Repository\Pear;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
/** /**
* PEAR Channel package reader. * PEAR Channel package reader.
@ -26,12 +26,12 @@ class ChannelReader extends BaseChannelReader
/** @var array of ('xpath test' => 'rest implementation') */ /** @var array of ('xpath test' => 'rest implementation') */
private $readerMap; private $readerMap;
public function __construct(RemoteFilesystem $rfs) public function __construct(HttpDownloader $httpDownloader)
{ {
parent::__construct($rfs); parent::__construct($httpDownloader);
$rest10reader = new ChannelRest10Reader($rfs); $rest10reader = new ChannelRest10Reader($httpDownloader);
$rest11reader = new ChannelRest11Reader($rfs); $rest11reader = new ChannelRest11Reader($httpDownloader);
$this->readerMap = array( $this->readerMap = array(
'REST1.3' => $rest11reader, 'REST1.3' => $rest11reader,

@ -13,6 +13,7 @@
namespace Composer\Repository\Pear; namespace Composer\Repository\Pear;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
use Composer\Util\HttpDownloader;
/** /**
* Read PEAR packages using REST 1.0 interface * Read PEAR packages using REST 1.0 interface
@ -29,9 +30,9 @@ class ChannelRest10Reader extends BaseChannelReader
{ {
private $dependencyReader; private $dependencyReader;
public function __construct($rfs) public function __construct(HttpDownloader $httpDownloader)
{ {
parent::__construct($rfs); parent::__construct($httpDownloader);
$this->dependencyReader = new PackageDependencyParser(); $this->dependencyReader = new PackageDependencyParser();
} }

@ -12,6 +12,8 @@
namespace Composer\Repository\Pear; namespace Composer\Repository\Pear;
use Composer\Util\HttpDownloader;
/** /**
* Read PEAR packages using REST 1.1 interface * Read PEAR packages using REST 1.1 interface
* *
@ -25,9 +27,9 @@ class ChannelRest11Reader extends BaseChannelReader
{ {
private $dependencyReader; private $dependencyReader;
public function __construct($rfs) public function __construct(HttpDownloader $httpDownloader)
{ {
parent::__construct($rfs); parent::__construct($httpDownloader);
$this->dependencyReader = new PackageDependencyParser(); $this->dependencyReader = new PackageDependencyParser();
} }

@ -21,7 +21,7 @@ use Composer\Repository\Pear\ChannelInfo;
use Composer\EventDispatcher\EventDispatcher; use Composer\EventDispatcher\EventDispatcher;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
use Composer\Config; use Composer\Config;
use Composer\Factory; use Composer\Factory;
@ -38,7 +38,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
{ {
private $url; private $url;
private $io; private $io;
private $rfs; private $httpDownloader;
private $versionParser; private $versionParser;
private $repoConfig; private $repoConfig;
@ -47,7 +47,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
*/ */
private $vendorAlias; private $vendorAlias;
public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, RemoteFilesystem $rfs = null) public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher, HttpDownloader $httpDownloader)
{ {
parent::__construct(); parent::__construct();
if (!preg_match('{^https?://}', $repoConfig['url'])) { if (!preg_match('{^https?://}', $repoConfig['url'])) {
@ -61,7 +61,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
$this->url = rtrim($repoConfig['url'], '/'); $this->url = rtrim($repoConfig['url'], '/');
$this->io = $io; $this->io = $io;
$this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $config); $this->httpDownloader = $httpDownloader;
$this->vendorAlias = isset($repoConfig['vendor-alias']) ? $repoConfig['vendor-alias'] : null; $this->vendorAlias = isset($repoConfig['vendor-alias']) ? $repoConfig['vendor-alias'] : null;
$this->versionParser = new VersionParser(); $this->versionParser = new VersionParser();
$this->repoConfig = $repoConfig; $this->repoConfig = $repoConfig;
@ -78,7 +78,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
$this->io->writeError('Initializing PEAR repository '.$this->url); $this->io->writeError('Initializing PEAR repository '.$this->url);
$reader = new ChannelReader($this->rfs); $reader = new ChannelReader($this->httpDownloader);
try { try {
$channelInfo = $reader->read($this->url); $channelInfo = $reader->read($this->url);
} catch (\Exception $e) { } catch (\Exception $e) {

@ -108,12 +108,12 @@ class RepositoryFactory
* @param IOInterface $io * @param IOInterface $io
* @param Config $config * @param Config $config
* @param EventDispatcher $eventDispatcher * @param EventDispatcher $eventDispatcher
* @param HttpDownloader $rfs * @param HttpDownloader $httpDownloader
* @return RepositoryManager * @return RepositoryManager
*/ */
public static function manager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
{ {
$rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs); $rm = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader);
$rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository'); $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
$rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository'); $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository'); $rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');

@ -33,14 +33,14 @@ class RepositoryManager
private $io; private $io;
private $config; private $config;
private $eventDispatcher; private $eventDispatcher;
private $rfs; private $httpDownloader;
public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null) public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, HttpDownloader $httpDownloader)
{ {
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->rfs = $rfs; $this->httpDownloader = $httpDownloader;
} }
/** /**
@ -128,7 +128,7 @@ class RepositoryManager
$reflMethod = new \ReflectionMethod($class, '__construct'); $reflMethod = new \ReflectionMethod($class, '__construct');
$params = $reflMethod->getParameters(); $params = $reflMethod->getParameters();
if (isset($params[4]) && $params[4]->getClass() && $params[4]->getClass()->getName() === 'Composer\Util\HttpDownloader') { if (isset($params[4]) && $params[4]->getClass() && $params[4]->getClass()->getName() === 'Composer\Util\HttpDownloader') {
return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->rfs); return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->httpDownloader);
} }
return new $class($config, $this->io, $this->config, $this->eventDispatcher); return new $class($config, $this->io, $this->config, $this->eventDispatcher);

@ -16,6 +16,7 @@ use Composer\Cache;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Util\Bitbucket; use Composer\Util\Bitbucket;
use Composer\Util\Http\Response;
abstract class BitbucketDriver extends VcsDriver abstract class BitbucketDriver extends VcsDriver
{ {
@ -92,7 +93,7 @@ abstract class BitbucketDriver extends VcsDriver
) )
); );
$repoData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource, true), $resource); $repoData = $this->fetchWithOAuthCredentials($resource, true)->decodeJson();
if ($this->fallbackDriver) { if ($this->fallbackDriver) {
return false; return false;
} }
@ -204,7 +205,7 @@ abstract class BitbucketDriver extends VcsDriver
$file $file
); );
return $this->getContentsWithOAuthCredentials($resource); return $this->fetchWithOAuthCredentials($resource)->getBody();
} }
/** /**
@ -222,7 +223,7 @@ abstract class BitbucketDriver extends VcsDriver
$this->repository, $this->repository,
$identifier $identifier
); );
$commit = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); $commit = $this->fetchWithOAuthCredentials($resource)->decodeJson();
return new \DateTime($commit['date']); return new \DateTime($commit['date']);
} }
@ -284,7 +285,7 @@ abstract class BitbucketDriver extends VcsDriver
); );
$hasNext = true; $hasNext = true;
while ($hasNext) { while ($hasNext) {
$tagsData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); $tagsData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
foreach ($tagsData['values'] as $data) { foreach ($tagsData['values'] as $data) {
$this->tags[$data['name']] = $data['target']['hash']; $this->tags[$data['name']] = $data['target']['hash'];
} }
@ -328,7 +329,7 @@ abstract class BitbucketDriver extends VcsDriver
); );
$hasNext = true; $hasNext = true;
while ($hasNext) { while ($hasNext) {
$branchData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); $branchData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
foreach ($branchData['values'] as $data) { foreach ($branchData['values'] as $data) {
// skip headless branches which seem to be deleted branches that bitbucket nevertheless returns in the API // skip headless branches which seem to be deleted branches that bitbucket nevertheless returns in the API
if ($this->vcsType === 'hg' && empty($data['heads'])) { if ($this->vcsType === 'hg' && empty($data['heads'])) {
@ -354,14 +355,14 @@ abstract class BitbucketDriver extends VcsDriver
* @param string $url The URL of content * @param string $url The URL of content
* @param bool $fetchingRepoData * @param bool $fetchingRepoData
* *
* @return mixed The result * @return Response The result
*/ */
protected function getContentsWithOAuthCredentials($url, $fetchingRepoData = false) protected function fetchWithOAuthCredentials($url, $fetchingRepoData = false)
{ {
try { try {
return parent::getContents($url); return parent::getContents($url);
} catch (TransportException $e) { } catch (TransportException $e) {
$bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->remoteFilesystem); $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->httpDownloader);
if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) { if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) {
if (!$this->io->hasAuthentication($this->originUrl) if (!$this->io->hasAuthentication($this->originUrl)
@ -371,7 +372,9 @@ abstract class BitbucketDriver extends VcsDriver
} }
if (!$this->io->isInteractive() && $fetchingRepoData) { if (!$this->io->isInteractive() && $fetchingRepoData) {
return $this->attemptCloneFallback(); if ($this->attemptCloneFallback()) {
return new Response(array('url' => 'dummy'), 200, array(), 'null');
}
} }
} }
@ -390,6 +393,8 @@ abstract class BitbucketDriver extends VcsDriver
{ {
try { try {
$this->setupFallbackDriver($this->generateSshUrl()); $this->setupFallbackDriver($this->generateSshUrl());
return true;
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
$this->fallbackDriver = null; $this->fallbackDriver = null;
@ -433,7 +438,7 @@ abstract class BitbucketDriver extends VcsDriver
$this->repository $this->repository
); );
$data = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource); $data = $this->fetchWithOAuthCredentials($resource)->decodeJson();
if (isset($data['mainbranch'])) { if (isset($data['mainbranch'])) {
return $data['mainbranch']; return $data['mainbranch'];
} }

@ -76,7 +76,7 @@ class GitBitbucketDriver extends BitbucketDriver
$this->io, $this->io,
$this->config, $this->config,
$this->process, $this->process,
$this->remoteFilesystem $this->httpDownloader
); );
$this->fallbackDriver->initialize(); $this->fallbackDriver->initialize();
} }

@ -18,6 +18,8 @@ use Composer\Json\JsonFile;
use Composer\Cache; use Composer\Cache;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Util\GitHub; use Composer\Util\GitHub;
use Composer\Util\Http\Response;
use Composer\Util\RemoteFilesystem;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -184,7 +186,7 @@ class GitHubDriver extends VcsDriver
} }
$resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier); $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier);
$resource = JsonFile::parseJson($this->getContents($resource)); $resource = $this->getContents($resource)->decodeJson();
if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) { if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) {
throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier); throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier);
} }
@ -202,7 +204,7 @@ class GitHubDriver extends VcsDriver
} }
$resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier); $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
$commit = JsonFile::parseJson($this->getContents($resource), $resource); $commit = $this->getContents($resource)->decodeJson();
return new \DateTime($commit['commit']['committer']['date']); return new \DateTime($commit['commit']['committer']['date']);
} }
@ -220,12 +222,13 @@ class GitHubDriver extends VcsDriver
$resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100'; $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100';
do { do {
$tagsData = JsonFile::parseJson($this->getContents($resource), $resource); $response = $this->getContents($resource);
$tagsData = $response->decodeJson();
foreach ($tagsData as $tag) { foreach ($tagsData as $tag) {
$this->tags[$tag['name']] = $tag['commit']['sha']; $this->tags[$tag['name']] = $tag['commit']['sha'];
} }
$resource = $this->getNextPage(); $resource = $this->getNextPage($response);
} while ($resource); } while ($resource);
} }
@ -247,7 +250,8 @@ class GitHubDriver extends VcsDriver
$branchBlacklist = array('gh-pages'); $branchBlacklist = array('gh-pages');
do { do {
$branchData = JsonFile::parseJson($this->getContents($resource), $resource); $response = $this->getContents($resource);
$branchData = $response->decodeJson();
foreach ($branchData as $branch) { foreach ($branchData as $branch) {
$name = substr($branch['ref'], 11); $name = substr($branch['ref'], 11);
if (!in_array($name, $branchBlacklist)) { if (!in_array($name, $branchBlacklist)) {
@ -255,7 +259,7 @@ class GitHubDriver extends VcsDriver
} }
} }
$resource = $this->getNextPage(); $resource = $this->getNextPage($response);
} while ($resource); } while ($resource);
} }
@ -315,7 +319,7 @@ class GitHubDriver extends VcsDriver
try { try {
return parent::getContents($url); return parent::getContents($url);
} catch (TransportException $e) { } catch (TransportException $e) {
$gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem); $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->httpDownloader);
switch ($e->getCode()) { switch ($e->getCode()) {
case 401: case 401:
@ -330,16 +334,18 @@ class GitHubDriver extends VcsDriver
} }
if (!$this->io->isInteractive()) { if (!$this->io->isInteractive()) {
return $this->attemptCloneFallback(); if ($this->attemptCloneFallback()) {
return new Response(array('url' => 'dummy'), 200, array(), 'null');
}
} }
$scopesIssued = array(); $scopesIssued = array();
$scopesNeeded = array(); $scopesNeeded = array();
if ($headers = $e->getHeaders()) { if ($headers = $e->getHeaders()) {
if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-OAuth-Scopes')) { if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-OAuth-Scopes')) {
$scopesIssued = explode(' ', $scopes); $scopesIssued = explode(' ', $scopes);
} }
if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) { if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
$scopesNeeded = explode(' ', $scopes); $scopesNeeded = explode(' ', $scopes);
} }
} }
@ -358,7 +364,9 @@ class GitHubDriver extends VcsDriver
} }
if (!$this->io->isInteractive() && $fetchingRepoData) { if (!$this->io->isInteractive() && $fetchingRepoData) {
return $this->attemptCloneFallback(); if ($this->attemptCloneFallback()) {
return new Response(array('url' => 'dummy'), 200, array(), 'null');
}
} }
$rateLimited = $gitHubUtil->isRateLimited($e->getHeaders()); $rateLimited = $gitHubUtil->isRateLimited($e->getHeaders());
@ -404,7 +412,7 @@ class GitHubDriver extends VcsDriver
$repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository; $repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository;
$this->repoData = JsonFile::parseJson($this->getContents($repoDataUrl, true), $repoDataUrl); $this->repoData = $this->getContents($repoDataUrl, true)->decodeJson();
if (null === $this->repoData && null !== $this->gitDriver) { if (null === $this->repoData && null !== $this->gitDriver) {
return; return;
} }
@ -434,7 +442,7 @@ class GitHubDriver extends VcsDriver
// are not interactive) then we fallback to GitDriver. // are not interactive) then we fallback to GitDriver.
$this->setupGitDriver($this->generateSshUrl()); $this->setupGitDriver($this->generateSshUrl());
return; return true;
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
$this->gitDriver = null; $this->gitDriver = null;
@ -450,22 +458,19 @@ class GitHubDriver extends VcsDriver
$this->io, $this->io,
$this->config, $this->config,
$this->process, $this->process,
$this->remoteFilesystem $this->httpDownloader
); );
$this->gitDriver->initialize(); $this->gitDriver->initialize();
} }
protected function getNextPage() protected function getNextPage(Response $response)
{ {
$headers = $this->remoteFilesystem->getLastHeaders(); $header = $response->getHeader('link');
foreach ($headers as $header) {
if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) { $links = explode(',', $header);
$links = explode(',', $match[1]); foreach ($links as $link) {
foreach ($links as $link) { if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { return $match[1];
return $match[1];
}
}
} }
} }
} }

@ -17,8 +17,9 @@ use Composer\Cache;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
use Composer\Util\GitLab; use Composer\Util\GitLab;
use Composer\Util\Http\Response;
/** /**
* Driver for GitLab API, use the Git driver for local checkouts. * Driver for GitLab API, use the Git driver for local checkouts.
@ -110,14 +111,14 @@ class GitLabDriver extends VcsDriver
} }
/** /**
* Updates the RemoteFilesystem instance. * Updates the HttpDownloader instance.
* Mainly useful for tests. * Mainly useful for tests.
* *
* @internal * @internal
*/ */
public function setRemoteFilesystem(RemoteFilesystem $remoteFilesystem) public function setHttpDownloader(HttpDownloader $httpDownloader)
{ {
$this->remoteFilesystem = $remoteFilesystem; $this->httpDownloader = $httpDownloader;
} }
/** /**
@ -140,7 +141,7 @@ class GitLabDriver extends VcsDriver
$resource = $this->getApiUrl().'/repository/files/'.$this->urlEncodeAll($file).'/raw?ref='.$identifier; $resource = $this->getApiUrl().'/repository/files/'.$this->urlEncodeAll($file).'/raw?ref='.$identifier;
try { try {
$content = $this->getContents($resource); $content = $this->getContents($resource)->getBody();
} catch (TransportException $e) { } catch (TransportException $e) {
if ($e->getCode() !== 404) { if ($e->getCode() !== 404) {
throw $e; throw $e;
@ -297,7 +298,8 @@ class GitLabDriver extends VcsDriver
$references = array(); $references = array();
do { do {
$data = JsonFile::parseJson($this->getContents($resource), $resource); $response = $this->getContents($resource);
$data = $response->decodeJson();
foreach ($data as $datum) { foreach ($data as $datum) {
$references[$datum['name']] = $datum['commit']['id']; $references[$datum['name']] = $datum['commit']['id'];
@ -308,7 +310,7 @@ class GitLabDriver extends VcsDriver
} }
if (count($data) >= $perPage) { if (count($data) >= $perPage) {
$resource = $this->getNextPage(); $resource = $this->getNextPage($response);
} else { } else {
$resource = false; $resource = false;
} }
@ -321,7 +323,7 @@ class GitLabDriver extends VcsDriver
{ {
// we need to fetch the default branch from the api // we need to fetch the default branch from the api
$resource = $this->getApiUrl(); $resource = $this->getApiUrl();
$this->project = JsonFile::parseJson($this->getContents($resource, true), $resource); $this->project = $this->getContents($resource, true)->decodeJson();
if (isset($this->project['visibility'])) { if (isset($this->project['visibility'])) {
$this->isPrivate = $this->project['visibility'] !== 'public'; $this->isPrivate = $this->project['visibility'] !== 'public';
} else { } else {
@ -344,7 +346,7 @@ class GitLabDriver extends VcsDriver
// are not interactive) then we fallback to GitDriver. // are not interactive) then we fallback to GitDriver.
$this->setupGitDriver($url); $this->setupGitDriver($url);
return; return true;
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
$this->gitDriver = null; $this->gitDriver = null;
@ -375,7 +377,7 @@ class GitLabDriver extends VcsDriver
$this->io, $this->io,
$this->config, $this->config,
$this->process, $this->process,
$this->remoteFilesystem $this->httpDownloader
); );
$this->gitDriver->initialize(); $this->gitDriver->initialize();
} }
@ -386,10 +388,10 @@ class GitLabDriver extends VcsDriver
protected function getContents($url, $fetchingRepoData = false) protected function getContents($url, $fetchingRepoData = false)
{ {
try { try {
$res = parent::getContents($url); $response = parent::getContents($url);
if ($fetchingRepoData) { if ($fetchingRepoData) {
$json = JsonFile::parseJson($res, $url); $json = $response->decodeJson();
// force auth as the unauthenticated version of the API is broken // force auth as the unauthenticated version of the API is broken
if (!isset($json['default_branch'])) { if (!isset($json['default_branch'])) {
@ -401,9 +403,9 @@ class GitLabDriver extends VcsDriver
} }
} }
return $res; return $response;
} catch (TransportException $e) { } catch (TransportException $e) {
$gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->remoteFilesystem); $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->httpDownloader);
switch ($e->getCode()) { switch ($e->getCode()) {
case 401: case 401:
@ -418,7 +420,9 @@ class GitLabDriver extends VcsDriver
} }
if (!$this->io->isInteractive()) { if (!$this->io->isInteractive()) {
return $this->attemptCloneFallback(); if ($this->attemptCloneFallback()) {
return new Response(array('url' => 'dummy'), 200, array(), 'null');
}
} }
$this->io->writeError('<warning>Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . '</warning>'); $this->io->writeError('<warning>Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . '</warning>');
$gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)'); $gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
@ -431,7 +435,9 @@ class GitLabDriver extends VcsDriver
} }
if (!$this->io->isInteractive() && $fetchingRepoData) { if (!$this->io->isInteractive() && $fetchingRepoData) {
return $this->attemptCloneFallback(); if ($this->attemptCloneFallback()) {
return new Response(array('url' => 'dummy'), 200, array(), 'null');
}
} }
throw $e; throw $e;
@ -471,17 +477,14 @@ class GitLabDriver extends VcsDriver
return true; return true;
} }
private function getNextPage() protected function getNextPage(Response $response)
{ {
$headers = $this->remoteFilesystem->getLastHeaders(); $header = $response->getHeader('link');
foreach ($headers as $header) {
if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) { $links = explode(',', $header);
$links = explode(',', $match[1]); foreach ($links as $link) {
foreach ($links as $link) { if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) { return $match[1];
return $match[1];
}
}
} }
} }
} }

@ -76,7 +76,7 @@ class HgBitbucketDriver extends BitbucketDriver
$this->io, $this->io,
$this->config, $this->config,
$this->process, $this->process,
$this->remoteFilesystem $this->httpDownloader
); );
$this->fallbackDriver->initialize(); $this->fallbackDriver->initialize();
} }

@ -19,8 +19,9 @@ use Composer\Factory;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Http\Response;
/** /**
* A driver implementation for driver with authentication interaction. * A driver implementation for driver with authentication interaction.
@ -41,8 +42,8 @@ abstract class VcsDriver implements VcsDriverInterface
protected $config; protected $config;
/** @var ProcessExecutor */ /** @var ProcessExecutor */
protected $process; protected $process;
/** @var RemoteFilesystem */ /** @var HttpDownloader */
protected $remoteFilesystem; protected $httpDownloader;
/** @var array */ /** @var array */
protected $infoCache = array(); protected $infoCache = array();
/** @var Cache */ /** @var Cache */
@ -55,9 +56,9 @@ abstract class VcsDriver implements VcsDriverInterface
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param Config $config The composer configuration * @param Config $config The composer configuration
* @param ProcessExecutor $process Process instance, injectable for mocking * @param ProcessExecutor $process Process instance, injectable for mocking
* @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
*/ */
final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
{ {
if (Filesystem::isLocalPath($repoConfig['url'])) { if (Filesystem::isLocalPath($repoConfig['url'])) {
$repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']); $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']);
@ -69,7 +70,7 @@ abstract class VcsDriver implements VcsDriverInterface
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
$this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
} }
/** /**
@ -156,13 +157,13 @@ abstract class VcsDriver implements VcsDriverInterface
* *
* @param string $url The URL of content * @param string $url The URL of content
* *
* @return mixed The result * @return Response
*/ */
protected function getContents($url) protected function getContents($url)
{ {
$options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array(); $options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array();
return $this->remoteFilesystem->getContents($this->originUrl, $url, false, $options); return $this->httpDownloader->get($url, $options);
} }
/** /**

@ -25,7 +25,7 @@ class Bitbucket
private $io; private $io;
private $config; private $config;
private $process; private $process;
private $remoteFilesystem; private $httpDownloader;
private $token = array(); private $token = array();
private $time; private $time;
@ -37,15 +37,15 @@ class Bitbucket
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param Config $config The composer configuration * @param Config $config The composer configuration
* @param ProcessExecutor $process Process instance, injectable for mocking * @param ProcessExecutor $process Process instance, injectable for mocking
* @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
* @param int $time Timestamp, injectable for mocking * @param int $time Timestamp, injectable for mocking
*/ */
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null, $time = null) public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null, $time = null)
{ {
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
$this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
$this->time = $time; $this->time = $time;
} }
@ -90,7 +90,7 @@ class Bitbucket
private function requestAccessToken($originUrl) private function requestAccessToken($originUrl)
{ {
try { try {
$json = $this->remoteFilesystem->getContents($originUrl, self::OAUTH2_ACCESS_TOKEN_URL, false, array( $response = $this->httpDownloader->get(self::OAUTH2_ACCESS_TOKEN_URL, array(
'retry-auth-failure' => false, 'retry-auth-failure' => false,
'http' => array( 'http' => array(
'method' => 'POST', 'method' => 'POST',
@ -98,7 +98,7 @@ class Bitbucket
), ),
)); ));
$this->token = json_decode($json, true); $this->token = $response->decodeJson();
} catch (TransportException $e) { } catch (TransportException $e) {
if ($e->getCode() === 400) { if ($e->getCode() === 400) {
$this->io->writeError('<error>Invalid OAuth consumer provided.</error>'); $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');

@ -25,7 +25,7 @@ class GitHub
protected $io; protected $io;
protected $config; protected $config;
protected $process; protected $process;
protected $remoteFilesystem; protected $httpDownloader;
/** /**
* Constructor. * Constructor.
@ -33,14 +33,14 @@ class GitHub
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param Config $config The composer configuration * @param Config $config The composer configuration
* @param ProcessExecutor $process Process instance, injectable for mocking * @param ProcessExecutor $process Process instance, injectable for mocking
* @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
*/ */
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
{ {
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
$this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
} }
/** /**
@ -104,7 +104,7 @@ class GitHub
try { try {
$apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/'; $apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/';
$this->remoteFilesystem->getContents($originUrl, 'https://'. $apiUrl, false, array( $this->httpDownloader->get('https://'. $apiUrl, array(
'retry-auth-failure' => false, 'retry-auth-failure' => false,
)); ));
} catch (TransportException $e) { } catch (TransportException $e) {

@ -26,7 +26,7 @@ class GitLab
protected $io; protected $io;
protected $config; protected $config;
protected $process; protected $process;
protected $remoteFilesystem; protected $httpDownloader;
/** /**
* Constructor. * Constructor.
@ -34,14 +34,14 @@ class GitLab
* @param IOInterface $io The IO instance * @param IOInterface $io The IO instance
* @param Config $config The composer configuration * @param Config $config The composer configuration
* @param ProcessExecutor $process Process instance, injectable for mocking * @param ProcessExecutor $process Process instance, injectable for mocking
* @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
*/ */
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
{ {
$this->io = $io; $this->io = $io;
$this->config = $config; $this->config = $config;
$this->process = $process ?: new ProcessExecutor($io); $this->process = $process ?: new ProcessExecutor($io);
$this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
} }
/** /**
@ -154,10 +154,10 @@ class GitLab
), ),
); );
$json = $this->remoteFilesystem->getContents($originUrl, $scheme.'://'.$apiUrl.'/oauth/token', false, $options); $token = $this->httpDownloader->get($scheme.'://'.$apiUrl.'/oauth/token', $options)->decodeJson();
$this->io->writeError('Token successfully created'); $this->io->writeError('Token successfully created');
return JsonFile::parseJson($json); return $token;
} }
} }

@ -23,6 +23,9 @@ class Response
public function __construct(array $request, $code, array $headers, $body) public function __construct(array $request, $code, array $headers, $body)
{ {
if (!isset($request['url'])) {
throw new \LogicException('url key missing from request array');
}
$this->request = $request; $this->request = $request;
$this->code = $code; $this->code = $code;
$this->headers = $headers; $this->headers = $headers;

@ -117,8 +117,8 @@ class HttpDownloader
$origin = $this->getOrigin($job['request']['url']); $origin = $this->getOrigin($job['request']['url']);
// TODO only send http/https through curl // TODO experiment with allowing file:// through curl too
if ($curl) { if ($curl && preg_match('{^https?://}i', $job['request']['url'])) {
$resolver = function ($resolve, $reject) use (&$job, $curl, $origin) { $resolver = function ($resolve, $reject) use (&$job, $curl, $origin) {
// start job // start job
$url = $job['request']['url']; $url = $job['request']['url'];
@ -141,11 +141,7 @@ class HttpDownloader
$job['status'] = HttpDownloader::STATUS_STARTED; $job['status'] = HttpDownloader::STATUS_STARTED;
if ($job['request']['copyTo']) { if ($job['request']['copyTo']) {
if ($curl) { $result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options);
$result = $curl->download($origin, $url, $options, $job['request']['copyTo']);
} else {
$result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options);
}
$resolve($result); $resolve($result);
} else { } else {

@ -147,7 +147,7 @@ class RemoteFilesystem
* @param string $name header name (case insensitive) * @param string $name header name (case insensitive)
* @return string|null * @return string|null
*/ */
public function findHeaderValue(array $headers, $name) public static function findHeaderValue(array $headers, $name)
{ {
$value = null; $value = null;
foreach ($headers as $header) { foreach ($headers as $header) {
@ -167,7 +167,7 @@ class RemoteFilesystem
* @param array $headers array of returned headers like from getLastHeaders() * @param array $headers array of returned headers like from getLastHeaders()
* @return int|null * @return int|null
*/ */
public function findStatusCode(array $headers) public static function findStatusCode(array $headers)
{ {
$value = null; $value = null;
foreach ($headers as $header) { foreach ($headers as $header) {

@ -156,7 +156,11 @@ class ArchiveDownloaderTest extends TestCase
{ {
return $this->getMockForAbstractClass( return $this->getMockForAbstractClass(
'Composer\Downloader\ArchiveDownloader', 'Composer\Downloader\ArchiveDownloader',
array($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\Config')->getMock()) array(
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$config = $this->getMockBuilder('Composer\Config')->getMock(),
new \Composer\Util\HttpDownloader($io, $config),
)
); );
} }
} }

@ -18,13 +18,13 @@ use Composer\Util\Filesystem;
class FileDownloaderTest extends TestCase class FileDownloaderTest extends TestCase
{ {
protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $rfs = null, $filesystem = null) protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $httpDownloader = null, $filesystem = null)
{ {
$io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$config = $config ?: $this->getMockBuilder('Composer\Config')->getMock(); $config = $config ?: $this->getMockBuilder('Composer\Config')->getMock();
$rfs = $rfs ?: $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock(); $httpDownloader = $httpDownloader ?: $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
return new FileDownloader($io, $config, $eventDispatcher, $cache, $rfs, $filesystem); return new FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $filesystem);
} }
/** /**

@ -16,7 +16,7 @@ use Composer\Downloader\XzDownloader;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
class XzDownloaderTest extends TestCase class XzDownloaderTest extends TestCase
{ {
@ -66,7 +66,7 @@ class XzDownloaderTest extends TestCase
->method('get') ->method('get')
->with('vendor-dir') ->with('vendor-dir')
->will($this->returnValue($this->testDir)); ->will($this->returnValue($this->testDir));
$downloader = new XzDownloader($io, $config, null, null, null, new RemoteFilesystem($io)); $downloader = new XzDownloader($io, $config, new HttpDownloader($io, $this->getMockBuilder('Composer\Config')->getMock()), null, null, null);
try { try {
$downloader->download($packageMock, $this->getUniqueTmpDirectory()); $downloader->download($packageMock, $this->getUniqueTmpDirectory());

@ -16,6 +16,7 @@ use Composer\Downloader\ZipDownloader;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\HttpDownloader;
class ZipDownloaderTest extends TestCase class ZipDownloaderTest extends TestCase
{ {
@ -32,6 +33,8 @@ class ZipDownloaderTest extends TestCase
$this->testDir = $this->getUniqueTmpDirectory(); $this->testDir = $this->getUniqueTmpDirectory();
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$this->config = $this->getMockBuilder('Composer\Config')->getMock(); $this->config = $this->getMockBuilder('Composer\Config')->getMock();
$dlConfig = $this->getMockBuilder('Composer\Config')->getMock();
$this->httpDownloader = new HttpDownloader($this->io, $dlConfig);
} }
public function tearDown() public function tearDown()
@ -64,18 +67,6 @@ class ZipDownloaderTest extends TestCase
} }
$this->config->expects($this->at(0)) $this->config->expects($this->at(0))
->method('get')
->with('disable-tls')
->will($this->returnValue(false));
$this->config->expects($this->at(1))
->method('get')
->with('cafile')
->will($this->returnValue(null));
$this->config->expects($this->at(2))
->method('get')
->with('capath')
->will($this->returnValue(null));
$this->config->expects($this->at(3))
->method('get') ->method('get')
->with('vendor-dir') ->with('vendor-dir')
->will($this->returnValue($this->testDir)); ->will($this->returnValue($this->testDir));
@ -94,7 +85,7 @@ class ZipDownloaderTest extends TestCase
->will($this->returnValue(array())) ->will($this->returnValue(array()))
; ;
$downloader = new ZipDownloader($this->io, $this->config); $downloader = new ZipDownloader($this->io, $this->config, $this->httpDownloader);
$this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasSystemUnzip', false);
@ -118,8 +109,7 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasSystemUnzip', false);
$this->setPrivateProperty('hasZipArchive', true); $this->setPrivateProperty('hasZipArchive', true);
$downloader = new MockedZipDownloader($this->io, $this->config); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
$zipArchive->expects($this->at(0)) $zipArchive->expects($this->at(0))
->method('open') ->method('open')
@ -144,8 +134,7 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasSystemUnzip', false);
$this->setPrivateProperty('hasZipArchive', true); $this->setPrivateProperty('hasZipArchive', true);
$downloader = new MockedZipDownloader($this->io, $this->config); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
$zipArchive->expects($this->at(0)) $zipArchive->expects($this->at(0))
->method('open') ->method('open')
@ -169,8 +158,7 @@ class ZipDownloaderTest extends TestCase
$this->setPrivateProperty('hasSystemUnzip', false); $this->setPrivateProperty('hasSystemUnzip', false);
$this->setPrivateProperty('hasZipArchive', true); $this->setPrivateProperty('hasZipArchive', true);
$downloader = new MockedZipDownloader($this->io, $this->config); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
$zipArchive = $this->getMockBuilder('ZipArchive')->getMock(); $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
$zipArchive->expects($this->at(0)) $zipArchive->expects($this->at(0))
->method('open') ->method('open')
@ -200,7 +188,7 @@ class ZipDownloaderTest extends TestCase
->method('execute') ->method('execute')
->will($this->returnValue(1)); ->will($this->returnValue(1));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }
@ -217,7 +205,7 @@ class ZipDownloaderTest extends TestCase
->method('execute') ->method('execute')
->will($this->returnValue(0)); ->will($this->returnValue(0));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }
@ -244,7 +232,7 @@ class ZipDownloaderTest extends TestCase
->method('extractTo') ->method('extractTo')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }
@ -276,7 +264,7 @@ class ZipDownloaderTest extends TestCase
->method('extractTo') ->method('extractTo')
->will($this->returnValue(false)); ->will($this->returnValue(false));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }
@ -304,7 +292,7 @@ class ZipDownloaderTest extends TestCase
->method('extractTo') ->method('extractTo')
->will($this->returnValue(false)); ->will($this->returnValue(false));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }
@ -336,7 +324,7 @@ class ZipDownloaderTest extends TestCase
->method('extractTo') ->method('extractTo')
->will($this->returnValue(false)); ->will($this->returnValue(false));
$downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor); $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
$this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader); $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
$downloader->extract('testfile.zip', 'vendor/dir'); $downloader->extract('testfile.zip', 'vendor/dir');
} }

@ -63,7 +63,9 @@ class InstallerTest extends TestCase
->getMock(); ->getMock();
$config = $this->getMockBuilder('Composer\Config')->getMock(); $config = $this->getMockBuilder('Composer\Config')->getMock();
$repositoryManager = new RepositoryManager($io, $config); $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock();
$httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
$repositoryManager = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader);
$repositoryManager->setLocalRepository(new InstalledArrayRepository()); $repositoryManager->setLocalRepository(new InstalledArrayRepository());
if (!is_array($repositories)) { if (!is_array($repositories)) {
@ -76,7 +78,6 @@ class InstallerTest extends TestCase
$locker = $this->getMockBuilder('Composer\Package\Locker')->disableOriginalConstructor()->getMock(); $locker = $this->getMockBuilder('Composer\Package\Locker')->disableOriginalConstructor()->getMock();
$installationManager = new InstallationManagerMock(); $installationManager = new InstallationManagerMock();
$eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock();
$autoloadGenerator = $this->getMockBuilder('Composer\Autoload\AutoloadGenerator')->disableOriginalConstructor()->getMock(); $autoloadGenerator = $this->getMockBuilder('Composer\Autoload\AutoloadGenerator')->disableOriginalConstructor()->getMock();
$installer = new Installer($io, $config, clone $rootPackage, $downloadManager, $repositoryManager, $locker, $installationManager, $eventDispatcher, $autoloadGenerator); $installer = new Installer($io, $config, clone $rootPackage, $downloadManager, $repositoryManager, $locker, $installationManager, $eventDispatcher, $autoloadGenerator);

@ -12,13 +12,11 @@
namespace Composer\Test\Mock; namespace Composer\Test\Mock;
use Composer\Util\RemoteFilesystem; use Composer\Util\HttpDownloader;
use Composer\Util\Http\Response;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
/** class HttpDownloaderMock extends HttpDownloader
* Remote filesystem mock
*/
class RemoteFilesystemMock extends RemoteFilesystem
{ {
protected $contentMap; protected $contentMap;
@ -30,10 +28,10 @@ class RemoteFilesystemMock extends RemoteFilesystem
$this->contentMap = $contentMap; $this->contentMap = $contentMap;
} }
public function getContents($originUrl, $fileUrl, $progress = true, $options = array()) public function get($fileUrl, $options = array())
{ {
if (!empty($this->contentMap[$fileUrl])) { if (!empty($this->contentMap[$fileUrl])) {
return $this->contentMap[$fileUrl]; return new Response(array('url' => $fileUrl), 200, array(), $this->contentMap[$fileUrl]);
} }
throw new TransportException('The "'.$fileUrl.'" file could not be downloaded (NOT FOUND)', 404); throw new TransportException('The "'.$fileUrl.'" file could not be downloaded (NOT FOUND)', 404);

@ -12,9 +12,11 @@
namespace Composer\Test\Package\Archiver; namespace Composer\Test\Package\Archiver;
use Composer\IO\NullIO;
use Composer\Factory; use Composer\Factory;
use Composer\Package\Archiver\ArchiveManager; use Composer\Package\Archiver\ArchiveManager;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Test\Mock\FactoryMock;
class ArchiveManagerTest extends ArchiverTest class ArchiveManagerTest extends ArchiverTest
{ {
@ -30,7 +32,12 @@ class ArchiveManagerTest extends ArchiverTest
parent::setUp(); parent::setUp();
$factory = new Factory(); $factory = new Factory();
$this->manager = $factory->createArchiveManager($factory->createConfig()); $dm = $factory->createDownloadManager(
$io = new NullIO,
$config = FactoryMock::createConfig(),
$factory->createHttpDownloader($io, $config)
);
$this->manager = $factory->createArchiveManager($factory->createConfig(), $dm);
$this->targetDir = $this->testDir.'/composer_archiver_tests'; $this->targetDir = $this->testDir.'/composer_archiver_tests';
} }

@ -18,7 +18,7 @@ use Composer\Repository\RepositoryInterface;
use Composer\Test\Mock\FactoryMock; use Composer\Test\Mock\FactoryMock;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Semver\VersionParser; use Composer\Package\Version\VersionParser;
class ComposerRepositoryTest extends TestCase class ComposerRepositoryTest extends TestCase
{ {
@ -37,6 +37,8 @@ class ComposerRepositoryTest extends TestCase
$repoConfig, $repoConfig,
new NullIO, new NullIO,
FactoryMock::createConfig(), FactoryMock::createConfig(),
$this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
$this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
)) ))
->getMock(); ->getMock();
@ -179,21 +181,29 @@ class ComposerRepositoryTest extends TestCase
), ),
); );
$rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')
->disableOriginalConstructor()
->getMock();
$httpDownloader->expects($this->at(0))
->method('get')
->with($url = 'http://example.org/packages.json')
->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array('search' => '/search.json?q=%query%&type=%type%'))));
$rfs->expects($this->at(0)) $httpDownloader->expects($this->at(1))
->method('getContents') ->method('get')
->with('example.org', 'http://example.org/packages.json', false) ->with($url = 'http://example.org/search.json?q=foo&type=composer-plugin')
->willReturn(json_encode(array('search' => '/search.json?q=%query%&type=%type%'))); ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode($result)));
$rfs->expects($this->at(1)) $httpDownloader->expects($this->at(2))
->method('getContents') ->method('get')
->with('example.org', 'http://example.org/search.json?q=foo&type=composer-plugin', false) ->with($url = 'http://example.org/search.json?q=foo&type=library')
->willReturn(json_encode($result)); ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array())));
$repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), null, $rfs); $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), $eventDispatcher, $httpDownloader);
$this->assertSame( $this->assertSame(
array(array('name' => 'foo', 'description' => null)), array(array('name' => 'foo', 'description' => null)),

@ -14,8 +14,8 @@ namespace Composer\Test\Repository;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Repository\PathRepository; use Composer\Repository\PathRepository;
use Composer\Semver\VersionParser;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Package\Version\VersionParser;
class PathRepositoryTest extends TestCase class PathRepositoryTest extends TestCase
{ {

@ -22,13 +22,13 @@ use Composer\Semver\VersionParser;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Package\CompletePackage; use Composer\Package\CompletePackage;
use Composer\Test\Mock\RemoteFilesystemMock; use Composer\Test\Mock\HttpDownloaderMock;
class ChannelReaderTest extends TestCase class ChannelReaderTest extends TestCase
{ {
public function testShouldBuildPackagesFromPearSchema() public function testShouldBuildPackagesFromPearSchema()
{ {
$rfs = new RemoteFilesystemMock(array( $rfs = new HttpDownloaderMock(array(
'http://pear.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://pear.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),
@ -50,11 +50,15 @@ class ChannelReaderTest extends TestCase
public function testShouldSelectCorrectReader() public function testShouldSelectCorrectReader()
{ {
$rfs = new RemoteFilesystemMock(array( $rfs = new HttpDownloaderMock(array(
'http://pear.1.0.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.0.xml'), 'http://pear.1.0.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.0.xml'),
'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'), 'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'),
'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'), 'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'),
'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'),
'http://test.loc/rest10/r/http_client/deps.1.2.1.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_deps.1.2.1.txt'),
'http://test.loc/rest10/p/http_request/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_info.xml'), 'http://test.loc/rest10/p/http_request/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_info.xml'),
'http://test.loc/rest10/r/http_request/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_allreleases.xml'),
'http://test.loc/rest10/r/http_request/deps.1.4.0.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_deps.1.4.0.txt'),
'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),

@ -13,13 +13,13 @@
namespace Composer\Test\Repository\Pear; namespace Composer\Test\Repository\Pear;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Test\Mock\RemoteFilesystemMock; use Composer\Test\Mock\HttpDownloaderMock;
class ChannelRest10ReaderTest extends TestCase class ChannelRest10ReaderTest extends TestCase
{ {
public function testShouldBuildPackagesFromPearSchema() public function testShouldBuildPackagesFromPearSchema()
{ {
$rfs = new RemoteFilesystemMock(array( $rfs = new HttpDownloaderMock(array(
'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'), 'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'),
'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'), 'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'),
'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'), 'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'),

@ -13,13 +13,13 @@
namespace Composer\Test\Repository\Pear; namespace Composer\Test\Repository\Pear;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Test\Mock\RemoteFilesystemMock; use Composer\Test\Mock\HttpDownloaderMock;
class ChannelRest11ReaderTest extends TestCase class ChannelRest11ReaderTest extends TestCase
{ {
public function testShouldBuildPackagesFromPearSchema() public function testShouldBuildPackagesFromPearSchema()
{ {
$rfs = new RemoteFilesystemMock(array( $rfs = new HttpDownloaderMock(array(
'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'), 'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'), 'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'), 'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),

@ -133,7 +133,7 @@ class PearRepositoryTest extends TestCase
$config = new \Composer\Config(); $config = new \Composer\Config();
$this->remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
@ -143,6 +143,6 @@ class PearRepositoryTest extends TestCase
protected function tearDown() protected function tearDown()
{ {
$this->repository = null; $this->repository = null;
$this->remoteFilesystem = null; $this->httpDownloader = null;
} }
} }

@ -21,7 +21,9 @@ class RepositoryFactoryTest extends TestCase
{ {
$manager = RepositoryFactory::manager( $manager = RepositoryFactory::manager(
$this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$this->getMockBuilder('Composer\Config')->getMock() $this->getMockBuilder('Composer\Config')->getMock(),
$this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(),
$this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock()
); );
$ref = new \ReflectionProperty($manager, 'repositoryClasses'); $ref = new \ReflectionProperty($manager, 'repositoryClasses');

@ -38,7 +38,8 @@ class RepositoryManagerTest extends TestCase
$rm = new RepositoryManager( $rm = new RepositoryManager(
$this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$this->getMockBuilder('Composer\Config')->getMock(), $this->getMockBuilder('Composer\Config')->getMock(),
$this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
$this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
); );
$repository1 = $this->getMockBuilder('Composer\Repository\RepositoryInterface')->getMock(); $repository1 = $this->getMockBuilder('Composer\Repository\RepositoryInterface')->getMock();
@ -61,7 +62,8 @@ class RepositoryManagerTest extends TestCase
$rm = new RepositoryManager( $rm = new RepositoryManager(
$this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
$config = $this->getMockBuilder('Composer\Config')->setMethods(array('get'))->getMock(), $config = $this->getMockBuilder('Composer\Config')->setMethods(array('get'))->getMock(),
$this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock() $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
$this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
); );
$tmpdir = $this->tmpdir; $tmpdir = $this->tmpdir;

@ -16,6 +16,7 @@ use Composer\Config;
use Composer\Repository\Vcs\GitBitbucketDriver; use Composer\Repository\Vcs\GitBitbucketDriver;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Http\Response;
/** /**
* @group bitbucket * @group bitbucket
@ -26,8 +27,8 @@ class GitBitbucketDriverTest extends TestCase
private $io; private $io;
/** @type \Composer\Config */ /** @type \Composer\Config */
private $config; private $config;
/** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */ /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */
private $rfs; private $httpDownloader;
/** @type string */ /** @type string */
private $home; private $home;
/** @type string */ /** @type string */
@ -46,7 +47,7 @@ class GitBitbucketDriverTest extends TestCase
), ),
)); ));
$this->rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
} }
@ -68,7 +69,7 @@ class GitBitbucketDriverTest extends TestCase
$this->io, $this->io,
$this->config, $this->config,
null, null,
$this->rfs $this->httpDownloader
); );
$driver->initialize(); $driver->initialize();
@ -83,15 +84,14 @@ class GitBitbucketDriverTest extends TestCase
'https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo if this is a mercurial bitbucket repository' 'https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo if this is a mercurial bitbucket repository'
); );
$this->rfs->expects($this->once()) $this->httpDownloader->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->originUrl, $url = 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner', array()
false
) )
->willReturn( ->willReturn(
'{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}' new Response(array('url' => $url), 200, array(), '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}')
); );
$driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git')); $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git'));
@ -103,47 +103,43 @@ class GitBitbucketDriverTest extends TestCase
{ {
$driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git')); $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git'));
$this->rfs->expects($this->any()) $urls = array(
->method('getContents') 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch',
'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date',
'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date',
'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json',
'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date',
);
$this->httpDownloader->expects($this->any())
->method('get')
->withConsecutive( ->withConsecutive(
array( array(
$this->originUrl, $urls[0], array()
'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
false,
), ),
array( array(
$this->originUrl, $urls[1], array()
'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch',
false,
), ),
array( array(
$this->originUrl, $urls[2], array()
'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date',
false,
), ),
array( array(
$this->originUrl, $urls[3], array()
'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date',
false,
), ),
array( array(
$this->originUrl, $urls[4], array()
'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json',
false,
), ),
array( array(
$this->originUrl, $urls[5], array()
'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date',
false,
) )
) )
->willReturnOnConsecutiveCalls( ->willReturnOnConsecutiveCalls(
'{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}', new Response(array('url' => $urls[0]), 200, array(), '{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'),
'{"mainbranch": {"name": "master"}}', new Response(array('url' => $urls[1]), 200, array(), '{"mainbranch": {"name": "master"}}'),
'{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}', new Response(array('url' => $urls[2]), 200, array(), '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'),
'{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}', new Response(array('url' => $urls[3]), 200, array(), '{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'),
'{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}', new Response(array('url' => $urls[4]), 200, array(), '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'),
'{"date": "2016-05-17T13:19:52+00:00"}' new Response(array('url' => $urls[5]), 200, array(), '{"date": "2016-05-17T13:19:52+00:00"}')
); );
$this->assertEquals( $this->assertEquals(

@ -16,6 +16,7 @@ use Composer\Downloader\TransportException;
use Composer\Repository\Vcs\GitHubDriver; use Composer\Repository\Vcs\GitHubDriver;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Http\Response;
use Composer\Config; use Composer\Config;
class GitHubDriverTest extends TestCase class GitHubDriverTest extends TestCase
@ -53,8 +54,8 @@ class GitHubDriverTest extends TestCase
->method('isInteractive') ->method('isInteractive')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->setConstructorArgs(array($io)) ->setConstructorArgs(array($io, $this->config))
->getMock(); ->getMock();
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
@ -62,9 +63,9 @@ class GitHubDriverTest extends TestCase
->method('execute') ->method('execute')
->will($this->returnValue(1)); ->will($this->returnValue(1));
$remoteFilesystem->expects($this->at(0)) $httpDownloader->expects($this->at(0))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) ->with($this->equalTo($repoApiUrl))
->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404))); ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
$io->expects($this->once()) $io->expects($this->once())
@ -76,15 +77,15 @@ class GitHubDriverTest extends TestCase
->method('setAuthentication') ->method('setAuthentication')
->with($this->equalTo('github.com'), $this->matchesRegularExpression('{sometoken}'), $this->matchesRegularExpression('{x-oauth-basic}')); ->with($this->equalTo('github.com'), $this->matchesRegularExpression('{sometoken}'), $this->matchesRegularExpression('{x-oauth-basic}'));
$remoteFilesystem->expects($this->at(1)) $httpDownloader->expects($this->at(1))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/'), $this->equalTo(false)) ->with($this->equalTo($url = 'https://api.github.com/'))
->will($this->returnValue('{}')); ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{}')));
$remoteFilesystem->expects($this->at(2)) $httpDownloader->expects($this->at(2))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) ->with($this->equalTo($url = $repoApiUrl))
->will($this->returnValue('{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}')); ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}')));
$configSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock(); $configSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock();
$authConfigSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock(); $authConfigSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock();
@ -95,7 +96,7 @@ class GitHubDriverTest extends TestCase
'url' => $repoUrl, 'url' => $repoUrl,
); );
$gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem); $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader);
$gitHubDriver->initialize(); $gitHubDriver->initialize();
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
@ -124,21 +125,21 @@ class GitHubDriverTest extends TestCase
->method('isInteractive') ->method('isInteractive')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->setConstructorArgs(array($io)) ->setConstructorArgs(array($io, $this->config))
->getMock(); ->getMock();
$remoteFilesystem->expects($this->at(0)) $httpDownloader->expects($this->at(0))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) ->with($this->equalTo($repoApiUrl))
->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')); ->will($this->returnValue(new Response(array('url' => $repoApiUrl), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')));
$repoConfig = array( $repoConfig = array(
'url' => $repoUrl, 'url' => $repoUrl,
); );
$repoUrl = 'https://github.com/composer/packagist.git'; $repoUrl = 'https://github.com/composer/packagist.git';
$gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem); $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader);
$gitHubDriver->initialize(); $gitHubDriver->initialize();
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
@ -167,31 +168,31 @@ class GitHubDriverTest extends TestCase
->method('isInteractive') ->method('isInteractive')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->setConstructorArgs(array($io)) ->setConstructorArgs(array($io, $this->config))
->getMock(); ->getMock();
$remoteFilesystem->expects($this->at(0)) $httpDownloader->expects($this->at(0))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) ->with($this->equalTo($url = $repoApiUrl))
->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')); ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')));
$remoteFilesystem->expects($this->at(1)) $httpDownloader->expects($this->at(1))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo'), $this->equalTo(false)) ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo'))
->will($this->returnValue('{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}')); ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}')));
$remoteFilesystem->expects($this->at(2)) $httpDownloader->expects($this->at(2))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo'), $this->equalTo(false)) ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo'))
->will($this->returnValue('{"commit": {"committer":{ "date": "2012-09-10"}}}')); ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"commit": {"committer":{ "date": "2012-09-10"}}}')));
$repoConfig = array( $repoConfig = array(
'url' => $repoUrl, 'url' => $repoUrl,
); );
$repoUrl = 'https://github.com/composer/packagist.git'; $repoUrl = 'https://github.com/composer/packagist.git';
$gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem); $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader);
$gitHubDriver->initialize(); $gitHubDriver->initialize();
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha)); $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
@ -227,13 +228,13 @@ class GitHubDriverTest extends TestCase
->method('isInteractive') ->method('isInteractive')
->will($this->returnValue(false)); ->will($this->returnValue(false));
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem') $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
->setConstructorArgs(array($io)) ->setConstructorArgs(array($io, $this->config))
->getMock(); ->getMock();
$remoteFilesystem->expects($this->at(0)) $httpDownloader->expects($this->at(0))
->method('getContents') ->method('get')
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false)) ->with($this->equalTo($repoApiUrl))
->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404))); ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
// clean local clone if present // clean local clone if present
@ -278,7 +279,7 @@ class GitHubDriverTest extends TestCase
'url' => $repoUrl, 'url' => $repoUrl,
); );
$gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem); $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader);
$gitHubDriver->initialize(); $gitHubDriver->initialize();
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier()); $this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());

@ -17,6 +17,7 @@ use Composer\Config;
use Composer\Test\TestCase; use Composer\Test\TestCase;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Prophecy\Argument; use Prophecy\Argument;
use Composer\Util\Http\Response;
/** /**
* @author Jérôme Tamarelle <jerome@tamarelle.net> * @author Jérôme Tamarelle <jerome@tamarelle.net>
@ -27,7 +28,7 @@ class GitLabDriverTest extends TestCase
private $config; private $config;
private $io; private $io;
private $process; private $process;
private $remoteFilesystem; private $httpDownloader;
public function setUp() public function setUp()
{ {
@ -47,7 +48,7 @@ class GitLabDriverTest extends TestCase
$this->io = $this->prophesize('Composer\IO\IOInterface'); $this->io = $this->prophesize('Composer\IO\IOInterface');
$this->process = $this->prophesize('Composer\Util\ProcessExecutor'); $this->process = $this->prophesize('Composer\Util\ProcessExecutor');
$this->remoteFilesystem = $this->prophesize('Composer\Util\RemoteFilesystem'); $this->httpDownloader = $this->prophesize('Composer\Util\HttpDownloader');
} }
public function tearDown() public function tearDown()
@ -87,13 +88,11 @@ class GitLabDriverTest extends TestCase
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -126,13 +125,11 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -164,13 +161,11 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -206,12 +201,10 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), sprintf($projectData, $domain, $port, $namespace))
->getContents($domain, $apiUrl, false, array())
->willReturn(sprintf($projectData, $domain, $port, $namespace))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -289,15 +282,11 @@ JSON;
] ]
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $tagData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($tagData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$this->remoteFilesystem->getLastHeaders()
->willReturn(array());
$driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); $driver->setHttpDownloader($this->httpDownloader->reveal());
$expected = array( $expected = array(
'v1.0.0' => '092ed2c762bbae331e3f51d4a17f67310bf99a81', 'v1.0.0' => '092ed2c762bbae331e3f51d4a17f67310bf99a81',
@ -344,26 +333,20 @@ JSON;
$branchData = json_encode($branchData); $branchData = json_encode($branchData);
$this->remoteFilesystem $headers = array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="next", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"');
->getContents('gitlab.com', $apiUrl, false, array()) $this->httpDownloader
->willReturn($branchData) ->get($apiUrl, array())
->shouldBeCalledTimes(1) ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData))
; ->shouldBeCalledTimes(1);
$this->remoteFilesystem
->getContents('gitlab.com', "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20", false, array())
->willReturn($branchData)
->shouldBeCalledTimes(1)
;
$this->remoteFilesystem->getLastHeaders() $apiUrl = "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20";
->willReturn( $headers = array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="prev", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"');
array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="next", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"'), $this->httpDownloader
array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="prev", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"') ->get($apiUrl, array())
) ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData))
->shouldBeCalledTimes(2); ->shouldBeCalledTimes(1);
$driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); $driver->setHttpDownloader($this->httpDownloader->reveal());
$expected = array( $expected = array(
'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e', 'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
@ -401,15 +384,11 @@ JSON;
] ]
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $branchData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($branchData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$this->remoteFilesystem->getLastHeaders()
->willReturn(array());
$driver->setRemoteFilesystem($this->remoteFilesystem->reveal()); $driver->setHttpDownloader($this->httpDownloader->reveal());
$expected = array( $expected = array(
'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e', 'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
@ -474,13 +453,11 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('mycompany.com/gitlab', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -507,13 +484,11 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('gitlab.com', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -540,13 +515,11 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse($apiUrl, array(), $projectData)
->getContents('mycompany.com/gitlab', $apiUrl, false, array())
->willReturn($projectData)
->shouldBeCalledTimes(1) ->shouldBeCalledTimes(1)
; ;
$driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal()); $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
$driver->initialize(); $driver->initialize();
$this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL'); $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@ -575,9 +548,7 @@ JSON;
} }
JSON; JSON;
$this->remoteFilesystem $this->mockResponse(Argument::cetera(), $options, $projectData)
->getContents(Argument::cetera(), $options)
->willReturn($projectData)
->shouldBeCalled(); ->shouldBeCalled();
$driver = new GitLabDriver( $driver = new GitLabDriver(
@ -585,8 +556,15 @@ JSON;
$this->io->reveal(), $this->io->reveal(),
$this->config, $this->config,
$this->process->reveal(), $this->process->reveal(),
$this->remoteFilesystem->reveal() $this->httpDownloader->reveal()
); );
$driver->initialize(); $driver->initialize();
} }
private function mockResponse($url, $options, $return)
{
return $this->httpDownloader
->get($url, $options)
->willReturn(new Response(array('url' => $url), 200, array(), $return));
}
} }

@ -26,7 +26,7 @@ class PerforceDriverTest extends TestCase
protected $config; protected $config;
protected $io; protected $io;
protected $process; protected $process;
protected $remoteFileSystem; protected $httpDownloader;
protected $testPath; protected $testPath;
protected $driver; protected $driver;
protected $repoConfig; protected $repoConfig;
@ -43,9 +43,9 @@ class PerforceDriverTest extends TestCase
$this->repoConfig = $this->getTestRepoConfig(); $this->repoConfig = $this->getTestRepoConfig();
$this->io = $this->getMockIOInterface(); $this->io = $this->getMockIOInterface();
$this->process = $this->getMockProcessExecutor(); $this->process = $this->getMockProcessExecutor();
$this->remoteFileSystem = $this->getMockRemoteFilesystem(); $this->httpDownloader = $this->getMockHttpDownloader();
$this->perforce = $this->getMockPerforce(); $this->perforce = $this->getMockPerforce();
$this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem); $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader);
$this->overrideDriverInternalPerforce($this->perforce); $this->overrideDriverInternalPerforce($this->perforce);
} }
@ -56,7 +56,7 @@ class PerforceDriverTest extends TestCase
$fs->removeDirectory($this->testPath); $fs->removeDirectory($this->testPath);
$this->driver = null; $this->driver = null;
$this->perforce = null; $this->perforce = null;
$this->remoteFileSystem = null; $this->httpDownloader = null;
$this->process = null; $this->process = null;
$this->io = null; $this->io = null;
$this->repoConfig = null; $this->repoConfig = null;
@ -99,9 +99,9 @@ class PerforceDriverTest extends TestCase
return $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); return $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
} }
protected function getMockRemoteFilesystem() protected function getMockHttpDownloader()
{ {
return $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock(); return $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
} }
protected function getMockPerforce() protected function getMockPerforce()
@ -113,7 +113,7 @@ class PerforceDriverTest extends TestCase
public function testInitializeCapturesVariablesFromRepoConfig() public function testInitializeCapturesVariablesFromRepoConfig()
{ {
$driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem); $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader);
$driver->initialize(); $driver->initialize();
$this->assertEquals(self::TEST_URL, $driver->getUrl()); $this->assertEquals(self::TEST_URL, $driver->getUrl());
$this->assertEquals(self::TEST_DEPOT, $driver->getDepot()); $this->assertEquals(self::TEST_DEPOT, $driver->getDepot());

@ -13,6 +13,7 @@
namespace Composer\Test\Util; namespace Composer\Test\Util;
use Composer\Util\Bitbucket; use Composer\Util\Bitbucket;
use Composer\Util\Http\Response;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
/** /**
@ -30,8 +31,8 @@ class BitbucketTest extends TestCase
/** @type \Composer\IO\ConsoleIO|\PHPUnit_Framework_MockObject_MockObject */ /** @type \Composer\IO\ConsoleIO|\PHPUnit_Framework_MockObject_MockObject */
private $io; private $io;
/** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */ /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */
private $rfs; private $httpDownloader;
/** @type \Composer\Config|\PHPUnit_Framework_MockObject_MockObject */ /** @type \Composer\Config|\PHPUnit_Framework_MockObject_MockObject */
private $config; private $config;
/** @type Bitbucket */ /** @type Bitbucket */
@ -47,8 +48,8 @@ class BitbucketTest extends TestCase
->getMock() ->getMock()
; ;
$this->rfs = $this $this->httpDownloader = $this
->getMockBuilder('Composer\Util\RemoteFilesystem') ->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock() ->getMock()
; ;
@ -57,7 +58,7 @@ class BitbucketTest extends TestCase
$this->time = time(); $this->time = time();
$this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->rfs, $this->time); $this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->httpDownloader, $this->time);
} }
public function testRequestAccessTokenWithValidOAuthConsumer() public function testRequestAccessTokenWithValidOAuthConsumer()
@ -66,12 +67,10 @@ class BitbucketTest extends TestCase
->method('setAuthentication') ->method('setAuthentication')
->with($this->origin, $this->consumer_key, $this->consumer_secret); ->with($this->origin, $this->consumer_key, $this->consumer_secret);
$this->rfs->expects($this->once()) $this->httpDownloader->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->origin,
Bitbucket::OAUTH2_ACCESS_TOKEN_URL, Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
false,
array( array(
'retry-auth-failure' => false, 'retry-auth-failure' => false,
'http' => array( 'http' => array(
@ -81,9 +80,14 @@ class BitbucketTest extends TestCase
) )
) )
->willReturn( ->willReturn(
sprintf( new Response(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL),
$this->token 200,
array(),
sprintf(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
$this->token
)
) )
); );
@ -142,12 +146,10 @@ class BitbucketTest extends TestCase
->method('setAuthentication') ->method('setAuthentication')
->with($this->origin, $this->consumer_key, $this->consumer_secret); ->with($this->origin, $this->consumer_key, $this->consumer_secret);
$this->rfs->expects($this->once()) $this->httpDownloader->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->origin,
Bitbucket::OAUTH2_ACCESS_TOKEN_URL, Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
false,
array( array(
'retry-auth-failure' => false, 'retry-auth-failure' => false,
'http' => array( 'http' => array(
@ -157,9 +159,14 @@ class BitbucketTest extends TestCase
) )
) )
->willReturn( ->willReturn(
sprintf( new Response(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}', array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL),
$this->token 200,
array(),
sprintf(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
$this->token
)
) )
); );
@ -186,12 +193,10 @@ class BitbucketTest extends TestCase
array('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url') array('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url')
); );
$this->rfs->expects($this->once()) $this->httpDownloader->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->origin,
Bitbucket::OAUTH2_ACCESS_TOKEN_URL, Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
false,
array( array(
'retry-auth-failure' => false, 'retry-auth-failure' => false,
'http' => array( 'http' => array(
@ -234,21 +239,24 @@ class BitbucketTest extends TestCase
) )
->willReturnOnConsecutiveCalls($this->consumer_key, $this->consumer_secret); ->willReturnOnConsecutiveCalls($this->consumer_key, $this->consumer_secret);
$this->rfs $this->httpDownloader
->expects($this->once()) ->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->equalTo($this->origin), $this->equalTo($url = sprintf('https://%s/site/oauth2/access_token', $this->origin)),
$this->equalTo(sprintf('https://%s/site/oauth2/access_token', $this->origin)),
$this->isFalse(),
$this->anything() $this->anything()
) )
->willReturn( ->willReturn(
sprintf( new Response(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}', array('url' => $url),
$this->token 200,
array(),
sprintf(
'{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}',
$this->token
)
) )
) );
; ;
$this->setExpectationsForStoringAccessToken(true); $this->setExpectationsForStoringAccessToken(true);

@ -14,6 +14,7 @@ namespace Composer\Test\Util;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
use Composer\Util\GitHub; use Composer\Util\GitHub;
use Composer\Util\Http\Response;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use RecursiveArrayIterator; use RecursiveArrayIterator;
use RecursiveIteratorIterator; use RecursiveIteratorIterator;
@ -45,17 +46,15 @@ class GitHubTest extends TestCase
->willReturn($this->password) ->willReturn($this->password)
; ;
$rfs = $this->getRemoteFilesystemMock(); $httpDownloader = $this->getHttpDownloaderMock();
$rfs $httpDownloader
->expects($this->once()) ->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->equalTo($this->origin), $this->equalTo($url = sprintf('https://api.%s/', $this->origin)),
$this->equalTo(sprintf('https://api.%s/', $this->origin)),
$this->isFalse(),
$this->anything() $this->anything()
) )
->willReturn('{}') ->willReturn(new Response(array('url' => $url), 200, array(), '{}'));
; ;
$config = $this->getConfigMock(); $config = $this->getConfigMock();
@ -70,7 +69,7 @@ class GitHubTest extends TestCase
->willReturn($this->getConfJsonMock()) ->willReturn($this->getConfJsonMock())
; ;
$github = new GitHub($io, $config, null, $rfs); $github = new GitHub($io, $config, null, $httpDownloader);
$this->assertTrue($github->authorizeOAuthInteractively($this->origin, $this->message)); $this->assertTrue($github->authorizeOAuthInteractively($this->origin, $this->message));
} }
@ -85,10 +84,10 @@ class GitHubTest extends TestCase
->willReturn($this->password) ->willReturn($this->password)
; ;
$rfs = $this->getRemoteFilesystemMock(); $httpDownloader = $this->getHttpDownloaderMock();
$rfs $httpDownloader
->expects($this->exactly(1)) ->expects($this->exactly(1))
->method('getContents') ->method('get')
->will($this->throwException(new TransportException('', 401))) ->will($this->throwException(new TransportException('', 401)))
; ;
@ -99,7 +98,7 @@ class GitHubTest extends TestCase
->willReturn($this->getAuthJsonMock()) ->willReturn($this->getAuthJsonMock())
; ;
$github = new GitHub($io, $config, null, $rfs); $github = new GitHub($io, $config, null, $httpDownloader);
$this->assertFalse($github->authorizeOAuthInteractively($this->origin)); $this->assertFalse($github->authorizeOAuthInteractively($this->origin));
} }
@ -120,15 +119,15 @@ class GitHubTest extends TestCase
return $this->getMockBuilder('Composer\Config')->getMock(); return $this->getMockBuilder('Composer\Config')->getMock();
} }
private function getRemoteFilesystemMock() private function getHttpDownloaderMock()
{ {
$rfs = $this $httpDownloader = $this
->getMockBuilder('Composer\Util\RemoteFilesystem') ->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock() ->getMock()
; ;
return $rfs; return $httpDownloader;
} }
private function getAuthJsonMock() private function getAuthJsonMock()

@ -14,6 +14,7 @@ namespace Composer\Test\Util;
use Composer\Downloader\TransportException; use Composer\Downloader\TransportException;
use Composer\Util\GitLab; use Composer\Util\GitLab;
use Composer\Util\Http\Response;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
/** /**
@ -49,17 +50,15 @@ class GitLabTest extends TestCase
->willReturn($this->password) ->willReturn($this->password)
; ;
$rfs = $this->getRemoteFilesystemMock(); $httpDownloader = $this->getHttpDownloaderMock();
$rfs $httpDownloader
->expects($this->once()) ->expects($this->once())
->method('getContents') ->method('get')
->with( ->with(
$this->equalTo($this->origin), $this->equalTo($url = sprintf('http://%s/oauth/token', $this->origin)),
$this->equalTo(sprintf('http://%s/oauth/token', $this->origin)),
$this->isFalse(),
$this->anything() $this->anything()
) )
->willReturn(sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token)) ->willReturn(new Response(array('url' => $url), 200, array(), sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token)));
; ;
$config = $this->getConfigMock(); $config = $this->getConfigMock();
@ -69,7 +68,7 @@ class GitLabTest extends TestCase
->willReturn($this->getAuthJsonMock()) ->willReturn($this->getAuthJsonMock())
; ;
$gitLab = new GitLab($io, $config, null, $rfs); $gitLab = new GitLab($io, $config, null, $httpDownloader);
$this->assertTrue($gitLab->authorizeOAuthInteractively('http', $this->origin, $this->message)); $this->assertTrue($gitLab->authorizeOAuthInteractively('http', $this->origin, $this->message));
} }
@ -94,10 +93,10 @@ class GitLabTest extends TestCase
->willReturn($this->password) ->willReturn($this->password)
; ;
$rfs = $this->getRemoteFilesystemMock(); $httpDownloader = $this->getHttpDownloaderMock();
$rfs $httpDownloader
->expects($this->exactly(5)) ->expects($this->exactly(5))
->method('getContents') ->method('get')
->will($this->throwException(new TransportException('', 401))) ->will($this->throwException(new TransportException('', 401)))
; ;
@ -108,7 +107,7 @@ class GitLabTest extends TestCase
->willReturn($this->getAuthJsonMock()) ->willReturn($this->getAuthJsonMock())
; ;
$gitLab = new GitLab($io, $config, null, $rfs); $gitLab = new GitLab($io, $config, null, $httpDownloader);
$gitLab->authorizeOAuthInteractively('https', $this->origin); $gitLab->authorizeOAuthInteractively('https', $this->origin);
} }
@ -129,15 +128,15 @@ class GitLabTest extends TestCase
return $this->getMockBuilder('Composer\Config')->getMock(); return $this->getMockBuilder('Composer\Config')->getMock();
} }
private function getRemoteFilesystemMock() private function getHttpDownloaderMock()
{ {
$rfs = $this $httpDownloader = $this
->getMockBuilder('Composer\Util\RemoteFilesystem') ->getMockBuilder('Composer\Util\HttpDownloader')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock() ->getMock()
; ;
return $rfs; return $httpDownloader;
} }
private function getAuthJsonMock() private function getAuthJsonMock()

Loading…
Cancel
Save