GithubURLParser { public GithubUrl parse(String url) { Matcher matcher = GITHUB_PATTERN.matcher(url); if (!matcher.matches()) { throw new IllegalArgumentException( String.format( "The given github url %s is not a valid URL github url. It should start with https: url)); } String repoUser = matcher.group("repoUser"); String repoName = matcher.group("repoName"); if (repoName.matches("^[\\w-][\\w.-]*?\\.git$")) { repoName = repoName.substring(0, repoName.length() - 4); } String branchName = matcher.group("branchName"); String pullRequestId = matcher.group("pullRequestId"); if (pullRequestId != null) { String prData = this.urlFetcher.fetchSafely(url); Matcher prMatcher = PR_DATA_PATTERN.matcher(prData); if (prMatcher.matches()) { String prState = prMatcher.group("prState"); if (!"open".equalsIgnoreCase(prState)) { throw new IllegalArgumentException( String.format( "The given Pull Request url %s is not Opened, (found %s), thus it can't be opened as branch may have been removed.", url, prState)); } repoUser = prMatcher.group("prRepoUser"); repoName = prMatcher.group("prRepoName"); branchName = prMatcher.group("prBranch"); } else { throw new IllegalArgumentException( String.format( "The given Pull Request github url %s is not a valid Pull Request URL github url. Unable to extract the data", url)); } } return new GithubUrl() .withUsername(repoUser) .withRepository(repoName) .withBranch(branchName) .withFactoryFilename(".factory.json") .withSubfolder(matcher.group("subFolder")) .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()); } @Inject  GithubURLParser(URLFetcher urlFetcher, DevfileFilenamesProvider devfileFilenamesProvider); boolean isValid(@NotNull String url); GithubUrl parse(String url);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void invalidUrl() { githubUrlParser.parse("http: }
@Test(dataProvider = "parsing") public void checkParsing( String url, String username, String repository, String branch, String subfolder) { GithubUrl githubUrl = githubUrlParser.parse(url); assertEquals(githubUrl.getUsername(), username); assertEquals(githubUrl.getRepository(), repository); assertEquals(githubUrl.getBranch(), branch); assertEquals(githubUrl.getSubfolder(), subfolder); }
@Test(dataProvider = "parsingBadRepository") public void checkParsingBadRepositoryDoNotModifiesInitialInput(String url, String repository) { GithubUrl githubUrl = githubUrlParser.parse(url); assertEquals(githubUrl.getRepository(), repository); }
@Test public void checkPullRequestFromRepository() { String url = "https: when(urlFetcher.fetchSafely(url)) .thenReturn( "<div class=\"TableObject gh-header-meta\">\n" + " <div class=\"TableObject-item\">\n" + " <div class=\"State State--green\">\n" + " <svg class=\"octicon octicon-git-pull-request\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n" + " Open\n" + " </div>\n" + "\n" + " </div>\n" + " <div class=\"TableObject-item TableObject-item--primary\">\n" + " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-type=\"user\" data-hovercard-url=\"/hovercards?user_id=1651062\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/mshaposhnik\">mshaposhnik</a>\n" + " wants to merge 1 commit into\n" + "\n" + "\n" + "\n" + " <span title=\"eclipse/che:cleanup-e2e-theia\" class=\"commit-ref css-truncate user-select-contain expandable \"><span class=\"css-truncate-target\">master</span></span>\n" + "\n" + "from\n" + "\n" + "<span title=\"eclipse/che:cleanup-e2e-theia\" class=\"commit-ref css-truncate user-select-contain expandable head-ref\"><span class=\"css-truncate-target\">cleanup-e2e-theia</span></span>\n" + "\n" + "\n" + " <relative-time datetime=\"2018-09-07T08:00:49Z\">Sep 7, 2018</relative-time>\n" + "\n" + " </div>\n" + " </div>\n" + "</div>"); GithubUrl githubUrl = githubUrlParser.parse(url); assertEquals(githubUrl.getUsername(), "eclipse"); assertEquals(githubUrl.getRepository(), "che"); assertEquals(githubUrl.getBranch(), "cleanup-e2e-theia"); }
@Test public void checkPullRequestFromForkedRepository() { String url = "https: when(urlFetcher.fetchSafely(url)) .thenReturn( "<div class=\"TableObject gh-header-meta\">\n" + " <div class=\"TableObject-item\">\n" + " <div class=\"State State--green\">\n" + " <svg class=\"octicon octicon-git-pull-request\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n" + " Open\n" + " </div>\n" + " </div>" + " <div class=\"TableObject-item TableObject-item--primary\">\n" + " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-user-id=\"436777\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/benoitf\">benoitf</a>\n" + " merged 1 commit into\n" + "from\n" + "\n" + "<span title=\"garagatyi/che:fixDeployment\" class=\"commit-ref css-truncate user-select-contain expandable head-ref\"><span class=\"css-truncate-target user\">garagatyi</span>:<span class=\"css-truncate-target\">fixDeployment</span></span>\n" + "\n"); GithubUrl githubUrl = githubUrlParser.parse(url); assertEquals(githubUrl.getUsername(), "garagatyi"); assertEquals(githubUrl.getRepository(), "che"); assertEquals(githubUrl.getBranch(), "fixDeployment"); }
@Test( expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*found Merged.*") public void checkPullRequestMergedState() { String url = "https: when(urlFetcher.fetchSafely(url)) .thenReturn( "\n" + " <div class=\"TableObject gh-header-meta\">\n" + " <div class=\"TableObject-item\">\n" + " <div class=\"State State--purple\">\n" + " <svg class=\"octicon octicon-git-merge\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M10 7c-.73 0-1.38.41-1.73 1.02V8C7.22 7.98 6 7.64 5.14 6.98c-.75-.58-1.5-1.61-1.89-2.44A1.993 1.993 0 0 0 2 .99C.89.99 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2a1.993 1.993 0 0 0 1-3.72V7.67c.67.7 1.44 1.27 2.3 1.69.86.42 2.03.63 2.97.64v-.02c.36.61 1 1.02 1.73 1.02 1.11 0 2-.89 2-2 0-1.11-.89-2-2-2zm-6.8 6c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm8 6c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n" + " Merged\n" + " </div>\n" + " </div>\n" + " <div class=\"TableObject-item TableObject-item--primary\">\n" + " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-user-id=\"436777\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/benoitf\">benoitf</a>\n" + " merged 1 commit into\n" + "\n" + "\n" + "\n" + " <span title=\"eclipse/che:master\" class=\"commit-ref css-truncate user-select-contain expandable \"><span class=\"css-truncate-target\">master</span></span>\n" + "\n" + "from\n" + "\n" + "<span title=\"eclipse/che:stack-theia\" class=\"commit-ref css-truncate user-select-contain expandable head-ref\"><span class=\"css-truncate-target\">stack-theia</span></span>\n" + "\n" + "\n" + " <relative-time datetime=\"2018-09-06T09:29:33Z\">Sep 6, 2018</relative-time>\n" + "\n" + " </div>\n" + " </div>\n" + "</div>\n"); githubUrlParser.parse(url); }
@Test( expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".*found Closed.*") public void checkPullRequestClosedState() { String url = "https: when(urlFetcher.fetchSafely(url)) .thenReturn( " <div class=\"TableObject gh-header-meta\">\n" + " <div class=\"TableObject-item\">\n" + " <div class=\"State State--red\">\n" + " <svg class=\"octicon octicon-git-pull-request\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n" + " Closed\n" + " </div>\n" + " </div>\n" + " <div class=\"TableObject-item TableObject-item--primary\">\n" + " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-user-id=\"436777\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/benoitf\">benoitf</a>\n" + " wants to merge 1 commit into\n" + "\n" + "\n" + "\n" + " <span title=\"eclipse/che:che6\" class=\"commit-ref css-truncate user-select-contain expandable base-ref\"><span class=\"css-truncate-target\">che6</span></span>\n" + "\n" + " <div class=\"commit-ref-dropdown\">\n" + " <details class=\"details-reset details-overlay select-menu js-select-menu commitish-suggester js-load-contents\" data-contents-url=\"/eclipse/che/pull/7923/show_partial?partial=pull_requests%2Fdescription_branches_dropdown\">\n" + " <summary class=\"btn btn-sm select-menu-button branch\" title=\"Choose a base branch\" aria-haspopup=\"true\">\n" + " <i>base:</i>\n" + " <span class=\"js-select-button css-truncate css-truncate-target\" title=\"che6\">che6</span>\n" + " </summary>\n" + " <details-menu class=\"select-menu-modal position-absolute\" style=\"z-index: 90;\">\n" + " <div class=\"js-select-menu-deferred-content\"></div>\n" + " <div class=\"select-menu-loading-overlay anim-pulse\">\n" + " <svg height=\"32\" class=\"octicon octicon-octoface\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"32\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M14.7 5.34c.13-.32.55-1.59-.13-3.31 0 0-1.05-.33-3.44 1.3-1-.28-2.07-.32-3.13-.32s-2.13.04-3.13.32c-2.39-1.64-3.44-1.3-3.44-1.3-.68 1.72-.26 2.99-.13 3.31C.49 6.21 0 7.33 0 8.69 0 13.84 3.33 15 7.98 15S16 13.84 16 8.69c0-1.36-.49-2.48-1.3-3.35zM8 14.02c-3.3 0-5.98-.15-5.98-3.35 0-.76.38-1.48 1.02-2.07 1.07-.98 2.9-.46 4.96-.46 2.07 0 3.88-.52 4.96.46.65.59 1.02 1.3 1.02 2.07 0 3.19-2.68 3.35-5.98 3.35zM5.49 9.01c-.66 0-1.2.8-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.54-1.78-1.2-1.78zm5.02 0c-.66 0-1.2.79-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.53-1.78-1.2-1.78z\"/></svg>\n" + " </div>\n" + " </details-menu>\n" + " </details>\n" + " </div>\n" + "\n" + "from\n" + "\n" + "<span title=\"eclipse/che:gwt-mockito\" class=\"commit-ref css-truncate user-select-contain expandable head-ref\"><span class=\"css-truncate-target\">gwt-mockito</span></span>\n" + "\n" + "\n" + "\n" + " </div>"); githubUrlParser.parse(url); }