ConfigTest.php 11 KB

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