GitLabDriverTest.php 14 KB

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