ConfigTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Test;
  12. use Composer\Config;
  13. class ConfigTest extends \PHPUnit_Framework_TestCase
  14. {
  15. /**
  16. * @dataProvider dataAddPackagistRepository
  17. */
  18. public function testAddPackagistRepository($expected, $localConfig, $systemConfig = null)
  19. {
  20. $config = new Config(false);
  21. if ($systemConfig) {
  22. $config->merge(array('repositories' => $systemConfig));
  23. }
  24. $config->merge(array('repositories' => $localConfig));
  25. $this->assertEquals($expected, $config->getRepositories());
  26. }
  27. public function dataAddPackagistRepository()
  28. {
  29. $data = array();
  30. $data['local config inherits system defaults'] = array(
  31. array(
  32. 'packagist.org' => array('type' => 'composer', 'url' => 'https?://packagist.org', 'allow_ssl_downgrade' => true),
  33. ),
  34. array(),
  35. );
  36. $data['local config can disable system config by name'] = array(
  37. array(),
  38. array(
  39. array('packagist.org' => false),
  40. ),
  41. );
  42. $data['local config can disable system config by name bc'] = array(
  43. array(),
  44. array(
  45. array('packagist' => false),
  46. ),
  47. );
  48. $data['local config adds above defaults'] = array(
  49. array(
  50. 1 => array('type' => 'vcs', 'url' => 'git://github.com/composer/composer.git'),
  51. 0 => array('type' => 'pear', 'url' => 'http://pear.composer.org'),
  52. 'packagist.org' => array('type' => 'composer', 'url' => 'https?://packagist.org', 'allow_ssl_downgrade' => true),
  53. ),
  54. array(
  55. array('type' => 'vcs', 'url' => 'git://github.com/composer/composer.git'),
  56. array('type' => 'pear', 'url' => 'http://pear.composer.org'),
  57. ),
  58. );
  59. $data['system config adds above core defaults'] = array(
  60. array(
  61. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  62. 'packagist.org' => array('type' => 'composer', 'url' => 'https?://packagist.org', 'allow_ssl_downgrade' => true),
  63. ),
  64. array(),
  65. array(
  66. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  67. ),
  68. );
  69. $data['local config can disable repos by name and re-add them anonymously to bring them above system config'] = array(
  70. array(
  71. 0 => array('type' => 'composer', 'url' => 'http://packagist.org'),
  72. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  73. ),
  74. array(
  75. array('packagist.org' => false),
  76. array('type' => 'composer', 'url' => 'http://packagist.org'),
  77. ),
  78. array(
  79. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  80. ),
  81. );
  82. $data['local config can override by name to bring a repo above system config'] = array(
  83. array(
  84. 'packagist.org' => array('type' => 'composer', 'url' => 'http://packagistnew.org'),
  85. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  86. ),
  87. array(
  88. 'packagist.org' => array('type' => 'composer', 'url' => 'http://packagistnew.org'),
  89. ),
  90. array(
  91. 'example.com' => array('type' => 'composer', 'url' => 'http://example.com'),
  92. ),
  93. );
  94. $data['incorrect local config does not cause ErrorException'] = array(
  95. array(
  96. 'packagist.org' => array('type' => 'composer', 'url' => 'https?://packagist.org', 'allow_ssl_downgrade' => true),
  97. 'type' => 'vcs',
  98. 'url' => 'http://example.com',
  99. ),
  100. array(
  101. 'type' => 'vcs',
  102. 'url' => 'http://example.com',
  103. ),
  104. );
  105. return $data;
  106. }
  107. public function testPreferredInstallAsString()
  108. {
  109. $config = new Config(false);
  110. $config->merge(array('config' => array('preferred-install' => 'source')));
  111. $config->merge(array('config' => array('preferred-install' => 'dist')));
  112. $this->assertEquals('dist', $config->get('preferred-install'));
  113. }
  114. public function testMergePreferredInstall()
  115. {
  116. $config = new Config(false);
  117. $config->merge(array('config' => array('preferred-install' => 'dist')));
  118. $config->merge(array('config' => array('preferred-install' => array('foo/*' => 'source'))));
  119. // This assertion needs to make sure full wildcard preferences are placed last
  120. // Handled by composer because we convert string preferences for BC, all other
  121. // care for ordering and collision prevention is up to the user
  122. $this->assertEquals(array('foo/*' => 'source', '*' => 'dist'), $config->get('preferred-install'));
  123. }
  124. public function testMergeGithubOauth()
  125. {
  126. $config = new Config(false);
  127. $config->merge(array('config' => array('github-oauth' => array('foo' => 'bar'))));
  128. $config->merge(array('config' => array('github-oauth' => array('bar' => 'baz'))));
  129. $this->assertEquals(array('foo' => 'bar', 'bar' => 'baz'), $config->get('github-oauth'));
  130. }
  131. public function testVarReplacement()
  132. {
  133. $config = new Config(false);
  134. $config->merge(array('config' => array('a' => 'b', 'c' => '{$a}')));
  135. $config->merge(array('config' => array('bin-dir' => '$HOME', 'cache-dir' => '~/foo/')));
  136. $home = rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '\\/');
  137. $this->assertEquals('b', $config->get('c'));
  138. $this->assertEquals($home, $config->get('bin-dir'));
  139. $this->assertEquals($home.'/foo', $config->get('cache-dir'));
  140. }
  141. public function testRealpathReplacement()
  142. {
  143. $config = new Config(false, '/foo/bar');
  144. $config->merge(array('config' => array(
  145. 'bin-dir' => '$HOME/foo',
  146. 'cache-dir' => '/baz/',
  147. 'vendor-dir' => 'vendor',
  148. )));
  149. $home = rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '\\/');
  150. $this->assertEquals('/foo/bar/vendor', $config->get('vendor-dir'));
  151. $this->assertEquals($home.'/foo', $config->get('bin-dir'));
  152. $this->assertEquals('/baz', $config->get('cache-dir'));
  153. }
  154. public function testStreamWrapperDirs()
  155. {
  156. $config = new Config(false, '/foo/bar');
  157. $config->merge(array('config' => array(
  158. 'cache-dir' => 's3://baz/',
  159. )));
  160. $this->assertEquals('s3://baz', $config->get('cache-dir'));
  161. }
  162. public function testFetchingRelativePaths()
  163. {
  164. $config = new Config(false, '/foo/bar');
  165. $config->merge(array('config' => array(
  166. 'bin-dir' => '{$vendor-dir}/foo',
  167. 'vendor-dir' => 'vendor',
  168. )));
  169. $this->assertEquals('/foo/bar/vendor', $config->get('vendor-dir'));
  170. $this->assertEquals('/foo/bar/vendor/foo', $config->get('bin-dir'));
  171. $this->assertEquals('vendor', $config->get('vendor-dir', Config::RELATIVE_PATHS));
  172. $this->assertEquals('vendor/foo', $config->get('bin-dir', Config::RELATIVE_PATHS));
  173. }
  174. public function testOverrideGithubProtocols()
  175. {
  176. $config = new Config(false);
  177. $config->merge(array('config' => array('github-protocols' => array('https', 'ssh'))));
  178. $config->merge(array('config' => array('github-protocols' => array('https'))));
  179. $this->assertEquals(array('https'), $config->get('github-protocols'));
  180. }
  181. public function testGitDisabledByDefaultInGithubProtocols()
  182. {
  183. $config = new Config(false);
  184. $config->merge(array('config' => array('github-protocols' => array('https', 'git'))));
  185. $this->assertEquals(array('https'), $config->get('github-protocols'));
  186. $config->merge(array('config' => array('secure-http' => false)));
  187. $this->assertEquals(array('https', 'git'), $config->get('github-protocols'));
  188. }
  189. /**
  190. * @dataProvider allowedUrlProvider
  191. *
  192. * @param string $url
  193. */
  194. public function testAllowedUrlsPass($url)
  195. {
  196. $config = new Config(false);
  197. $config->prohibitUrlByConfig($url);
  198. }
  199. /**
  200. * @dataProvider prohibitedUrlProvider
  201. *
  202. * @param string $url
  203. */
  204. public function testProhibitedUrlsThrowException($url)
  205. {
  206. $this->setExpectedException(
  207. 'Composer\Downloader\TransportException',
  208. 'Your configuration does not allow connections to ' . $url
  209. );
  210. $config = new Config(false);
  211. $config->prohibitUrlByConfig($url);
  212. }
  213. /**
  214. * @return array List of test URLs that should pass strict security
  215. */
  216. public function allowedUrlProvider()
  217. {
  218. $urls = array(
  219. 'https://packagist.org',
  220. 'git@github.com:composer/composer.git',
  221. 'hg://user:pass@my.satis/satis',
  222. '\\myserver\myplace.git',
  223. 'file://myserver.localhost/mygit.git',
  224. 'file://example.org/mygit.git',
  225. 'git:Department/Repo.git',
  226. 'ssh://[user@]host.xz[:port]/path/to/repo.git/',
  227. );
  228. return array_combine($urls, array_map(function ($e) { return array($e); }, $urls));
  229. }
  230. /**
  231. * @return array List of test URLs that should not pass strict security
  232. */
  233. public function prohibitedUrlProvider()
  234. {
  235. $urls = array(
  236. 'http://packagist.org',
  237. 'http://10.1.0.1/satis',
  238. 'http://127.0.0.1/satis',
  239. 'svn://localhost/trunk',
  240. 'svn://will.not.resolve/trunk',
  241. 'svn://192.168.0.1/trunk',
  242. 'svn://1.2.3.4/trunk',
  243. 'git://5.6.7.8/git.git',
  244. );
  245. return array_combine($urls, array_map(function ($e) { return array($e); }, $urls));
  246. }
  247. /**
  248. * @group TLS
  249. */
  250. public function testDisableTlsCanBeOverridden()
  251. {
  252. $config = new Config;
  253. $config->merge(
  254. array('config' => array('disable-tls' => 'false'))
  255. );
  256. $this->assertFalse($config->get('disable-tls'));
  257. $config->merge(
  258. array('config' => array('disable-tls' => 'true'))
  259. );
  260. $this->assertTrue($config->get('disable-tls'));
  261. }
  262. public function testProcessTimeout()
  263. {
  264. putenv('COMPOSER_PROCESS_TIMEOUT=0');
  265. $config = new Config(true);
  266. $this->assertEquals(0, $config->get('process-timeout'));
  267. putenv('COMPOSER_PROCESS_TIMEOUT');
  268. }
  269. }