001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm.provider.git.repository;
020
021import org.apache.maven.scm.ScmTestCase;
022import org.apache.maven.scm.manager.NoSuchScmProviderException;
023import org.apache.maven.scm.manager.ScmManager;
024import org.apache.maven.scm.repository.ScmRepository;
025import org.apache.maven.scm.repository.ScmRepositoryException;
026import org.junit.Before;
027import org.junit.Ignore;
028import org.junit.Test;
029
030import static org.junit.Assert.assertEquals;
031import static org.junit.Assert.assertNotNull;
032import static org.junit.Assert.assertTrue;
033import static org.junit.Assert.fail;
034
035/**
036 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
037 *
038 */
039public class GitScmProviderRepositoryTest extends ScmTestCase {
040    private ScmManager scmManager;
041
042    @Before
043    @Override
044    public void setUp() throws Exception {
045        super.setUp();
046
047        scmManager = getScmManager();
048    }
049
050    // ----------------------------------------------------------------------
051    // Testing legal URLs
052    // ----------------------------------------------------------------------
053
054    @Test
055    public void testLegalFileURL() throws Exception {
056        testUrl("scm:git:file:///tmp/repo", null, "file:///tmp/repo", null, null, null, null, 0, null);
057    }
058
059    @Test
060    public void testLegalFileHomeURL() throws Exception {
061        testUrl("scm:git:file://~/repo", null, "file://~/repo", null, null, null, null, 0, null);
062    }
063
064    @Test
065    public void testLegalSshHomeURL() throws Exception {
066        testUrl("scm:git:ssh://~/repo", null, "ssh://~/repo", null, null, null, null, 0, null);
067    }
068
069    @Test
070    public void testLegalLocalhostFileURL() throws Exception {
071        testUrl(
072                "scm:git:file://somedirectory/tmp/repo",
073                null,
074                "file://somedirectory/tmp/repo",
075                null,
076                null,
077                null,
078                null,
079                0,
080                "somedirectory/tmp/repo");
081    }
082
083    @Test
084    public void testLegalHistnameFileURL() throws Exception {
085        testUrl(
086                "scm:git:file://my_server/tmp/repo",
087                null,
088                "file://my_server/tmp/repo",
089                null,
090                null,
091                null,
092                null,
093                0,
094                "my_server/tmp/repo");
095    }
096
097    @Test
098    public void testLegalHttpURL() throws Exception {
099        testUrl(
100                "scm:git:http://gitrepos.apache.org",
101                null,
102                "http://gitrepos.apache.org",
103                null,
104                null,
105                null,
106                "gitrepos.apache.org",
107                0,
108                null);
109    }
110
111    @Test
112    public void testLegalHttpURLWithUser() throws Exception {
113        testUrl(
114                "scm:git:http://user@gitrepos.apache.org",
115                null,
116                "http://user@gitrepos.apache.org",
117                null,
118                "user",
119                null,
120                "gitrepos.apache.org",
121                0,
122                null);
123    }
124
125    @Test
126    public void testLegalHttpURLWithUserPassword() throws Exception {
127        testUrl(
128                "scm:git:http://user:password@gitrepos.apache.org",
129                null,
130                "http://user:password@gitrepos.apache.org",
131                null,
132                "user",
133                "password",
134                "gitrepos.apache.org",
135                0,
136                null);
137    }
138
139    @Test
140    public void testLegalHttpsURL() throws Exception {
141        testUrl(
142                "scm:git:https://gitrepos.apache.org/repos/projectA",
143                null,
144                "https://gitrepos.apache.org/repos/projectA",
145                null,
146                null,
147                null,
148                "gitrepos.apache.org",
149                0,
150                "repos/projectA");
151    }
152
153    @Test
154    public void testLegalFileWindowsURL() throws Exception {
155        // FIXME This URL is invalid, hell knows why Git accepts it. It should be by us right away
156        testUrl("scm:git:file://c:\\tmp\\repo", null, "file://c:\\tmp\\repo", null, null, null, null, 0, null);
157    }
158
159    @Test
160    public void testLegalHttpsURLWithUser() throws Exception {
161        testUrl(
162                "scm:git:https://user@gitrepos.apache.org",
163                null,
164                "https://user@gitrepos.apache.org",
165                null,
166                "user",
167                null,
168                "gitrepos.apache.org",
169                0,
170                null);
171    }
172
173    @Test
174    public void testLegalHttpsURLWithUserPassword() throws Exception {
175        testUrl(
176                "scm:git:https://user:password@gitrepos.apache.org",
177                null,
178                "https://user:password@gitrepos.apache.org",
179                null,
180                "user",
181                "password",
182                "gitrepos.apache.org",
183                0,
184                null);
185    }
186
187    @Test
188    public void testLegalSshURLWithUser() throws Exception {
189        testUrl(
190                "scm:git:ssh://user@gitrepos.apache.org",
191                null,
192                "ssh://user@gitrepos.apache.org",
193                null,
194                "user",
195                null,
196                "gitrepos.apache.org",
197                0,
198                null);
199    }
200
201    @Test
202    public void testLegalSshURLWithUserPassword() throws Exception {
203        testUrl(
204                "scm:git:ssh://user:password@gitrepos.apache.org",
205                null,
206                "ssh://user:password@gitrepos.apache.org",
207                null,
208                "user",
209                "password",
210                "gitrepos.apache.org",
211                0,
212                null);
213    }
214
215    @Test
216    public void testLegalGitURL() throws Exception {
217        testUrl(
218                "scm:git:git://gitrepos.apache.org",
219                null,
220                "git://gitrepos.apache.org",
221                null,
222                null,
223                null,
224                "gitrepos.apache.org",
225                0,
226                null);
227    }
228
229    @Test
230    public void testGitDevURL() throws Exception, ScmRepositoryException {
231        testUrl(
232                "scm:git:git@github.com:olamy/scm-git-test-one-module.git",
233                null,
234                "git@github.com:olamy/scm-git-test-one-module.git",
235                null,
236                "git",
237                null,
238                "github.com",
239                0,
240                null);
241    }
242
243    @Test
244    public void testGitDevURLWIthPort() throws Exception, ScmRepositoryException {
245        testUrl(
246                "scm:git:git@github.com:222:olamy/scm-git-test-one-module.git",
247                null,
248                "git@github.com:222:olamy/scm-git-test-one-module.git",
249                null,
250                "git",
251                null,
252                "github.com",
253                222,
254                null);
255    }
256
257    // For SCM-639
258    @Test
259    public void testGitDevUrlWithNumberedRepoAndNoPort() throws Exception, ScmRepositoryException {
260        testUrl(
261                "scm:git:git@github.com:4sh/blah.git",
262                null,
263                "git@github.com:4sh/blah.git",
264                null,
265                "git",
266                null,
267                "github.com",
268                0,
269                null);
270    }
271
272    // For SCM-629
273    @Test
274    public void testGitDevUrlWithNumberedRepoAndMinus() throws Exception, ScmRepositoryException {
275        testUrl(
276                "scm:git:ssh://git@github.com/360-Innovations/FJPAQuery.git",
277                null,
278                "ssh://git@github.com/360-Innovations/FJPAQuery.git",
279                null,
280                "git",
281                null,
282                "github.com",
283                0,
284                null);
285    }
286
287    // For SCM-707
288    @Test
289    public void testSpecialCharacters() throws Exception {
290        testUrl(
291                "scm:git:http://gitrepos.apache.org",
292                "@_&_:_?_#_%20",
293                "pass word",
294                null,
295                "http://gitrepos.apache.org",
296                null,
297                "http://%40_&_:_%3F_%23_%2520:pass%20word@gitrepos.apache.org",
298                null,
299                "gitrepos.apache.org",
300                0,
301                null);
302
303        testUrl(
304                "scm:git:http://gitrepos.apache.org",
305                "user name",
306                "@_&_:_?_#_%20",
307                null,
308                "http://gitrepos.apache.org",
309                null,
310                "http://user%20name:%40_&_:_%3F_%23_%2520@gitrepos.apache.org",
311                null,
312                "gitrepos.apache.org",
313                0,
314                null);
315    }
316
317    @Test
318    public void testLegalGitPortUrl() throws Exception {
319        testUrl(
320                "scm:git:http://username@gitrepos.apache.org:8800/pmgt/trunk",
321                null,
322                "http://username@gitrepos.apache.org:8800/pmgt/trunk",
323                null,
324                "username",
325                null,
326                "gitrepos.apache.org",
327                8800,
328                null);
329
330        testUrl(
331                "scm:git:https://username@gitrepos.apache.org:20443/pmgt/trunk",
332                null,
333                "https://username@gitrepos.apache.org:20443/pmgt/trunk",
334                null,
335                "username",
336                null,
337                "gitrepos.apache.org",
338                20443,
339                null);
340
341        testUrl(
342                "scm:git:git://username@gitrepos.apache.org:8800/pmgt/trunk",
343                null,
344                "git://username@gitrepos.apache.org:8800/pmgt/trunk",
345                null,
346                "username",
347                null,
348                "gitrepos.apache.org",
349                8800,
350                null);
351
352        testUrl(
353                "scm:git:ssh://username@gitrepos.apache.org:8080/pmgt/trunk",
354                null,
355                "ssh://username@gitrepos.apache.org:8080/pmgt/trunk",
356                null,
357                "username",
358                null,
359                "gitrepos.apache.org",
360                8080,
361                null);
362
363        testUrl(
364                "scm:git:ssh://username:password@gitrepos.apache.org/pmgt/trunk",
365                null,
366                "ssh://username:password@gitrepos.apache.org/pmgt/trunk",
367                null,
368                "username",
369                "password",
370                "gitrepos.apache.org",
371                0,
372                null);
373    }
374
375    @Test
376    public void testUsernameWithAtAndPasswordInUrl() throws ScmRepositoryException, Exception {
377        testUrl(
378                "scm:git:http://username@site.com:password@gitrepos.apache.org:8800/pmgt/trunk",
379                null,
380                "http://username%40site.com:password@gitrepos.apache.org:8800/pmgt/trunk",
381                null,
382                "username@site.com",
383                "password",
384                "gitrepos.apache.org",
385                8800,
386                null);
387    }
388
389    // ----------------------------------------------------------------------
390    // the following tests are for combined fetch + push URLs
391    // ----------------------------------------------------------------------
392
393    @Test
394    public void testHttpFetchSshPushUrl() throws Exception {
395        testUrl(
396                "scm:git:[fetch=]http://git.apache.org/myprj.git[push=]ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git",
397                "[fetch=]http://myuser:mypassword@git.apache.org/myprj.git[push=]ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git",
398                "http://myuser:mypassword@git.apache.org/myprj.git",
399                "ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git",
400                "myuser",
401                "mypassword",
402                "git.apache.org",
403                0,
404                null);
405
406        testUrl(
407                "scm:git:[push=]ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git[fetch=]http://git.apache.org/myprj.git",
408                "[fetch=]http://myuser:mypassword@git.apache.org/myprj.git[push=]ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git",
409                "http://myuser:mypassword@git.apache.org/myprj.git",
410                "ssh://myuser:mypassword@git.apache.org/~/myrepo/myprj.git",
411                "myuser",
412                "mypassword",
413                "git.apache.org",
414                0,
415                null);
416    }
417
418    // ----------------------------------------------------------------------
419    // Testing illegal URLs
420    // ----------------------------------------------------------------------
421
422    // X in fact this url is perfectly valid from a technical perspective
423    // X it will be interpreted by git as git://file/tmp/git
424    @Test
425    @Ignore
426    public void nottestIllegalFileUrl() throws Exception {
427        testIllegalUrl("file:/tmp/git");
428    }
429
430    // ----------------------------------------------------------------------
431    //
432    // ----------------------------------------------------------------------
433
434    private GitScmProviderRepository testUrl(
435            String scmUrl,
436            String expectedToString,
437            String expectedFetchUrl,
438            String expectedPushUrl,
439            String expectedUser,
440            String expectedPassword,
441            String expectedHost,
442            int expectedPort,
443            String expectedPath)
444            throws Exception, ScmRepositoryException {
445
446        ScmRepository repository = testScmRepository(scmUrl, expectedToString, expectedFetchUrl);
447
448        GitScmProviderRepository providerRepository = (GitScmProviderRepository) repository.getProviderRepository();
449
450        return testScmProviderRepository(
451                expectedToString,
452                expectedFetchUrl,
453                expectedPushUrl,
454                expectedUser,
455                expectedPassword,
456                expectedHost,
457                expectedPort,
458                providerRepository);
459    }
460
461    private GitScmProviderRepository testUrl(
462            String scmUrl,
463            String username,
464            String password,
465            String expectedScmRepositoryToString,
466            String expectedScmRepositoryFetchUrl,
467            String expectedScmProviderRepositoryToString,
468            String expectedScmProviderRepositoryFetchUrl,
469            String expectedPushUrl,
470            String expectedHost,
471            int expectedPort,
472            String expectedPath)
473            throws Exception, ScmRepositoryException {
474
475        ScmRepository repository =
476                testScmRepository(scmUrl, expectedScmRepositoryToString, expectedScmRepositoryFetchUrl);
477
478        GitScmProviderRepository providerRepository = (GitScmProviderRepository) repository.getProviderRepository();
479
480        providerRepository.setUser(username);
481
482        providerRepository.setPassword(password);
483
484        return testScmProviderRepository(
485                expectedScmProviderRepositoryToString,
486                expectedScmProviderRepositoryFetchUrl,
487                expectedPushUrl,
488                username,
489                password,
490                expectedHost,
491                expectedPort,
492                providerRepository);
493    }
494
495    private GitScmProviderRepository testScmProviderRepository(
496            String expectedToString,
497            String expectedFetchUrl,
498            String expectedPushUrl,
499            String expectedUser,
500            String expectedPassword,
501            String expectedHost,
502            int expectedPort,
503            GitScmProviderRepository providerRepository) {
504        assertEquals("fetch url is incorrect", expectedFetchUrl, providerRepository.getFetchUrl());
505
506        if (expectedPushUrl != null) {
507            assertEquals("push url is incorrect", expectedPushUrl, providerRepository.getPushUrl());
508        }
509
510        assertEquals("User is incorrect", expectedUser, providerRepository.getUser());
511
512        assertEquals("Password is incorrect", expectedPassword, providerRepository.getPassword());
513
514        assertEquals("Host is incorrect", expectedHost == null ? "" : expectedHost, providerRepository.getHost());
515
516        if (expectedPort > 0) {
517            assertEquals("Port is incorrect", expectedPort, providerRepository.getPort());
518        }
519
520        return providerRepository;
521    }
522
523    private ScmRepository testScmRepository(String scmUrl, String expectedToString, String expectedFetchUrl)
524            throws ScmRepositoryException, NoSuchScmProviderException {
525        ScmRepository repository = scmManager.makeScmRepository(scmUrl);
526
527        assertNotNull("ScmManager.makeScmRepository() returned null", repository);
528
529        assertNotNull("The provider repository was null.", repository.getProviderRepository());
530
531        assertTrue(
532                "The SCM Repository isn't a " + GitScmProviderRepository.class.getName() + ".",
533                repository.getProviderRepository() instanceof GitScmProviderRepository);
534
535        if (expectedToString != null) {
536            assertEquals("toString is incorrect", "git:" + expectedToString, repository.toString());
537        } else {
538            assertEquals("toString is incorrect", "git:" + expectedFetchUrl, repository.toString());
539        }
540
541        return repository;
542    }
543
544    private void testIllegalUrl(String url) throws Exception {
545        try {
546            scmManager.makeScmRepository("scm:git:" + url);
547
548            fail("Expected a ScmRepositoryException while testing the url '" + url + "'.");
549        } catch (ScmRepositoryException e) {
550            // expected
551        }
552    }
553
554    @Test
555    public void testGetParent() throws Exception {
556        new GitScmProviderRepository("http://gitrepos.apache.org");
557    }
558}