GitLabDriverTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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\Repository\Vcs;
  12. use Composer\Repository\Vcs\GitLabDriver;
  13. use Composer\Config;
  14. use Composer\TestCase;
  15. use Composer\Util\Filesystem;
  16. use Prophecy\Argument;
  17. /**
  18. * @author Jérôme Tamarelle <jerome@tamarelle.net>
  19. */
  20. class GitLabDriverTest extends TestCase
  21. {
  22. private $home;
  23. private $config;
  24. private $io;
  25. private $process;
  26. private $remoteFilesystem;
  27. public function setUp()
  28. {
  29. $this->home = $this->getUniqueTmpDirectory();
  30. $this->config = new Config();
  31. $this->config->merge(array(
  32. 'config' => array(
  33. 'home' => $this->home,
  34. 'gitlab-domains' => array('mycompany.com/gitlab', 'gitlab.com'),
  35. ),
  36. ));
  37. $this->io = $this->prophesize('Composer\IO\IOInterface');
  38. $this->process = $this->prophesize('Composer\Util\ProcessExecutor');
  39. $this->remoteFilesystem = $this->prophesize('Composer\Util\RemoteFilesystem');
  40. }
  41. public function tearDown()
  42. {
  43. $fs = new Filesystem();
  44. $fs->removeDirectory($this->home);
  45. }
  46. public function getInitializeUrls()
  47. {
  48. return array(
  49. array('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject'),
  50. array('http://gitlab.com/mygroup/myproject', 'http://gitlab.com/api/v3/projects/mygroup%2Fmyproject'),
  51. array('git@gitlab.com:mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject'),
  52. );
  53. }
  54. /**
  55. * @dataProvider getInitializeUrls
  56. */
  57. public function testInitialize($url, $apiUrl)
  58. {
  59. // @link http://doc.gitlab.com/ce/api/projects.html#get-single-project
  60. $projectData = <<<JSON
  61. {
  62. "id": 17,
  63. "default_branch": "mymaster",
  64. "public": false,
  65. "http_url_to_repo": "https://gitlab.com/mygroup/myproject.git",
  66. "ssh_url_to_repo": "git@gitlab.com:mygroup/myproject.git",
  67. "last_activity_at": "2014-12-01T09:17:51.000+01:00",
  68. "name": "My Project",
  69. "name_with_namespace": "My Group / My Project",
  70. "path": "myproject",
  71. "path_with_namespace": "mygroup/myproject",
  72. "web_url": "https://gitlab.com/mygroup/myproject"
  73. }
  74. JSON;
  75. $this->remoteFilesystem
  76. ->getContents('gitlab.com', $apiUrl, false, array())
  77. ->willReturn($projectData)
  78. ->shouldBeCalledTimes(1)
  79. ;
  80. $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
  81. $driver->initialize();
  82. $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
  83. $this->assertEquals('mymaster', $driver->getRootIdentifier(), 'Root identifier is the default branch in GitLab');
  84. $this->assertEquals('git@gitlab.com:mygroup/myproject.git', $driver->getRepositoryUrl(), 'The repository URL is the SSH one by default');
  85. $this->assertEquals('https://gitlab.com/mygroup/myproject', $driver->getUrl());
  86. return $driver;
  87. }
  88. /**
  89. * @dataProvider getInitializeUrls
  90. */
  91. public function testInitializePublicProject($url, $apiUrl)
  92. {
  93. // @link http://doc.gitlab.com/ce/api/projects.html#get-single-project
  94. $projectData = <<<JSON
  95. {
  96. "id": 17,
  97. "default_branch": "mymaster",
  98. "public": true,
  99. "http_url_to_repo": "https://gitlab.com/mygroup/myproject.git",
  100. "ssh_url_to_repo": "git@gitlab.com:mygroup/myproject.git",
  101. "last_activity_at": "2014-12-01T09:17:51.000+01:00",
  102. "name": "My Project",
  103. "name_with_namespace": "My Group / My Project",
  104. "path": "myproject",
  105. "path_with_namespace": "mygroup/myproject",
  106. "web_url": "https://gitlab.com/mygroup/myproject"
  107. }
  108. JSON;
  109. $this->remoteFilesystem
  110. ->getContents('gitlab.com', $apiUrl, false, array())
  111. ->willReturn($projectData)
  112. ->shouldBeCalledTimes(1)
  113. ;
  114. $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
  115. $driver->initialize();
  116. $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
  117. $this->assertEquals('mymaster', $driver->getRootIdentifier(), 'Root identifier is the default branch in GitLab');
  118. $this->assertEquals('https://gitlab.com/mygroup/myproject.git', $driver->getRepositoryUrl(), 'The repository URL is the SSH one by default');
  119. $this->assertEquals('https://gitlab.com/mygroup/myproject', $driver->getUrl());
  120. return $driver;
  121. }
  122. public function testGetDist()
  123. {
  124. $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject');
  125. $reference = 'c3ebdbf9cceddb82cd2089aaef8c7b992e536363';
  126. $expected = array(
  127. 'type' => 'zip',
  128. 'url' => 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject/repository/archive.zip?sha='.$reference,
  129. 'reference' => $reference,
  130. 'shasum' => '',
  131. );
  132. $this->assertEquals($expected, $driver->getDist($reference));
  133. }
  134. public function testGetSource()
  135. {
  136. $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject');
  137. $reference = 'c3ebdbf9cceddb82cd2089aaef8c7b992e536363';
  138. $expected = array(
  139. 'type' => 'git',
  140. 'url' => 'git@gitlab.com:mygroup/myproject.git',
  141. 'reference' => $reference,
  142. );
  143. $this->assertEquals($expected, $driver->getSource($reference));
  144. }
  145. public function testGetSource_GivenPublicProject()
  146. {
  147. $driver = $this->testInitializePublicProject('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject', true);
  148. $reference = 'c3ebdbf9cceddb82cd2089aaef8c7b992e536363';
  149. $expected = array(
  150. 'type' => 'git',
  151. 'url' => 'https://gitlab.com/mygroup/myproject.git',
  152. 'reference' => $reference,
  153. );
  154. $this->assertEquals($expected, $driver->getSource($reference));
  155. }
  156. public function testGetTags()
  157. {
  158. $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject');
  159. $apiUrl = 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject/repository/tags';
  160. // @link http://doc.gitlab.com/ce/api/repositories.html#list-project-repository-tags
  161. $tagData = <<<JSON
  162. [
  163. {
  164. "name": "v1.0.0",
  165. "commit": {
  166. "id": "092ed2c762bbae331e3f51d4a17f67310bf99a81",
  167. "committed_date": "2012-05-28T04:42:42-07:00"
  168. }
  169. },
  170. {
  171. "name": "v2.0.0",
  172. "commit": {
  173. "id": "8e8f60b3ec86d63733db3bd6371117a758027ec6",
  174. "committed_date": "2014-07-06T12:59:11.000+02:00"
  175. }
  176. }
  177. ]
  178. JSON;
  179. $this->remoteFilesystem
  180. ->getContents('gitlab.com', $apiUrl, false, array())
  181. ->willReturn($tagData)
  182. ->shouldBeCalledTimes(1)
  183. ;
  184. $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
  185. $expected = array(
  186. 'v1.0.0' => '092ed2c762bbae331e3f51d4a17f67310bf99a81',
  187. 'v2.0.0' => '8e8f60b3ec86d63733db3bd6371117a758027ec6',
  188. );
  189. $this->assertEquals($expected, $driver->getTags());
  190. $this->assertEquals($expected, $driver->getTags(), 'Tags are cached');
  191. }
  192. public function testGetBranches()
  193. {
  194. $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject');
  195. $apiUrl = 'https://gitlab.com/api/v3/projects/mygroup%2Fmyproject/repository/branches';
  196. // @link http://doc.gitlab.com/ce/api/repositories.html#list-project-repository-branches
  197. $branchData = <<<JSON
  198. [
  199. {
  200. "name": "mymaster",
  201. "commit": {
  202. "id": "97eda36b5c1dd953a3792865c222d4e85e5f302e",
  203. "committed_date": "2013-01-03T21:04:07.000+01:00"
  204. }
  205. },
  206. {
  207. "name": "staging",
  208. "commit": {
  209. "id": "502cffe49f136443f2059803f2e7192d1ac066cd",
  210. "committed_date": "2013-03-09T16:35:23.000+01:00"
  211. }
  212. }
  213. ]
  214. JSON;
  215. $this->remoteFilesystem
  216. ->getContents('gitlab.com', $apiUrl, false, array())
  217. ->willReturn($branchData)
  218. ->shouldBeCalledTimes(1)
  219. ;
  220. $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
  221. $expected = array(
  222. 'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
  223. 'staging' => '502cffe49f136443f2059803f2e7192d1ac066cd',
  224. );
  225. $this->assertEquals($expected, $driver->getBranches());
  226. $this->assertEquals($expected, $driver->getBranches(), 'Branches are cached');
  227. }
  228. /**
  229. * @dataProvider dataForTestSupports
  230. */
  231. public function testSupports($url, $expected)
  232. {
  233. $this->assertSame($expected, GitLabDriver::supports($this->io->reveal(), $this->config, $url));
  234. }
  235. public function dataForTestSupports()
  236. {
  237. return array(
  238. array('http://gitlab.com/foo/bar', true),
  239. array('http://gitlab.com/foo/bar/', true),
  240. array('http://gitlab.com/foo/bar.git', true),
  241. array('http://gitlab.com/foo/bar.baz.git', true),
  242. array('https://gitlab.com/foo/bar', extension_loaded('openssl')), // Platform requirement
  243. array('git@gitlab.com:foo/bar.git', extension_loaded('openssl')),
  244. array('git@example.com:foo/bar.git', false),
  245. array('http://example.com/foo/bar', false),
  246. array('http://mycompany.com/gitlab/mygroup/myproject', true),
  247. array('https://mycompany.com/gitlab/mygroup/myproject', extension_loaded('openssl')),
  248. );
  249. }
  250. public function testGitlabSubDirectory()
  251. {
  252. $url = 'https://mycompany.com/gitlab/mygroup/my-pro.ject';
  253. $apiUrl = 'https://mycompany.com/gitlab/api/v3/projects/mygroup%2Fmy-pro%2Eject';
  254. $projectData = <<<JSON
  255. {
  256. "id": 17,
  257. "default_branch": "mymaster",
  258. "public": false,
  259. "http_url_to_repo": "https://gitlab.com/mygroup/my-pro.ject",
  260. "ssh_url_to_repo": "git@gitlab.com:mygroup/my-pro.ject.git",
  261. "last_activity_at": "2014-12-01T09:17:51.000+01:00",
  262. "name": "My Project",
  263. "name_with_namespace": "My Group / My Project",
  264. "path": "myproject",
  265. "path_with_namespace": "mygroup/my-pro.ject",
  266. "web_url": "https://gitlab.com/mygroup/my-pro.ject"
  267. }
  268. JSON;
  269. $this->remoteFilesystem
  270. ->getContents('mycompany.com/gitlab', $apiUrl, false, array())
  271. ->willReturn($projectData)
  272. ->shouldBeCalledTimes(1)
  273. ;
  274. $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
  275. $driver->initialize();
  276. $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
  277. }
  278. public function testForwardsOptions()
  279. {
  280. $options = array(
  281. 'ssl' => array(
  282. 'verify_peer' => false,
  283. )
  284. );
  285. $projectData = <<<JSON
  286. {
  287. "id": 17,
  288. "default_branch": "mymaster",
  289. "public": false,
  290. "http_url_to_repo": "https://gitlab.mycompany.local/mygroup/myproject",
  291. "ssh_url_to_repo": "git@gitlab.mycompany.local:mygroup/myproject.git",
  292. "last_activity_at": "2014-12-01T09:17:51.000+01:00",
  293. "name": "My Project",
  294. "name_with_namespace": "My Group / My Project",
  295. "path": "myproject",
  296. "path_with_namespace": "mygroup/myproject",
  297. "web_url": "https://gitlab.mycompany.local/mygroup/myproject"
  298. }
  299. JSON;
  300. $this->remoteFilesystem
  301. ->getContents(Argument::cetera(), $options)
  302. ->willReturn($projectData)
  303. ->shouldBeCalled();
  304. $driver = new GitLabDriver(
  305. array('url' => 'https://gitlab.mycompany.local/mygroup/myproject', 'options' => $options),
  306. $this->io->reveal(),
  307. $this->config,
  308. $this->process->reveal(),
  309. $this->remoteFilesystem->reveal()
  310. );
  311. $driver->initialize();
  312. }
  313. }