package controllers; import models.Issue; import models.Project; import models.User; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryBuilder; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.RefSpec; import org.junit.*; import play.mvc.Result; import play.test.FakeApplication; import play.test.FakeRequest; import play.test.Helpers; import playRepository.GitRepository; import playRepository.RepositoryService; import support.ContextTest; import utils.RouteUtil; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import static org.fest.assertions.Assertions.assertThat; import static play.mvc.Http.Status.OK; import static play.test.Helpers.*; import static play.test.Helpers.contentAsString; /** * @author Changgun Kim */ public class MarkdownAppTest extends ContextTest { protected static FakeApplication app; private static User testOwner; private static Project testProject; private static User anotherOwner; private static Project anotherProject; private static Issue anotherIssue; @BeforeClass public static void beforeClass() { GitRepository.setRepoPrefix("resources/test/repo/git/"); Map<String, String> config = support.Helpers.makeTestConfig(); config.put("signup.require.confirm", "true"); app = support.Helpers.makeTestApplication(config); Helpers.start(app); callAction( routes.ref.Application.init() ); testOwner = createUser("testOwner", "testOwner@naver.com"); testProject = createProject(testOwner, "testProject"); anotherOwner = createUser("anotherIssueNumber", "anotherIssue@naver.com"); anotherProject = createProject(anotherOwner, "anotherIssueTestProject"); anotherIssue = createIssue(anotherOwner, anotherProject, "hello", "body"); GitRepository.setRepoPrefix("resources/test/repo/git/"); } @AfterClass public static void afterClass() { support.Files.rm_rf(new File(GitRepository.getRepoPrefix())); Helpers.stop(app); } private static User createUser(String name, String email) { User user = new User(); user.loginId = name; user.name = name; user.email = email; User.create(user); return user; } private static Project createProject(User owner, String name) { Project project = new Project(); project.owner = owner.name; project.name = name; project.vcs = RepositoryService.VCS_GIT; Project.create(project); return project; } private static Issue createIssue(User user, Project project, String title, String body) { Issue issue = new Issue(); issue.project = project; issue.setTitle(title); issue.setBody(body); issue.setAuthor(user); issue.save(); return issue; } private Repository createRepository(Project proejct) throws IOException { GitRepository gitRepository = new GitRepository(proejct.owner, proejct.name); gitRepository.create(); String wcPath = GitRepository.getRepoPrefix() + proejct.owner + "/" + "clone-" + proejct.name + ".git"; String repoPath = wcPath + "/.git"; Repository repository = new RepositoryBuilder().setGitDir(new File(repoPath)).build(); repository.create(false); return repository; } private RevCommit createCommit(Repository repository, User user, Project proejct) throws IOException, GitAPIException { String testDirName = "dir"; String testFileName = "file"; String wcPath = GitRepository.getRepoPrefix() + proejct.owner + "/" + "clone-" + proejct.name + ".git"; Git git = new Git(repository); FileUtils.forceMkdir(new File(wcPath + "/" + testDirName)); FileUtils.touch(new File(wcPath + "/" + testFileName)); git.add().addFilepattern(testDirName).call(); git.add().addFilepattern(testFileName).call(); RevCommit from = git.commit().setMessage("test").setAuthor(user.name, user.email).call(); String branchName = "testBranch"; git.branchCreate() .setName(branchName) .setForce(true) .call(); git.push() .setRemote(GitRepository.getGitDirectoryURL(proejct)) .setRefSpecs(new RefSpec(branchName + ":" + branchName)) .setForce(true) .call(); return from; } private FakeRequest makeFakeRequest(String body) { Map<String,String> data = new HashMap<>(); data.put("body", body); return fakeRequest().withFormUrlEncodedBody(data); } public String getCommitUrl(RevCommit commit, Project project) { if (commit == null) return null; return controllers.routes.CodeHistoryApp.show(project.owner, project.name, commit.name()).url(); } @Test public void test_ignorePattern() { // Given String notMatchBody = "nforge#12345 nforge/yobi#12345 #12345"; Issue notMatchIssue = createIssue(testOwner, testProject, "hello", notMatchBody); // When String body = "<a href='#'>#" + notMatchIssue.getNumber() + "</a>\n" + "<code>\nhttp://yobi.navercorp.com #" + notMatchIssue.getNumber() + " http://yobi.navercorp.com\n</code>\n" + "<div id='#" + notMatchIssue.getNumber() + "'>Test</div>"; Issue issue = createIssue(testOwner, testProject, "hello", body); Result result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(issue.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).doesNotContain(RouteUtil.getUrl(notMatchIssue)); } @Test public void test_WrappedPattern() { // Given String notMatchBody = "nforge#12345 nforge/yobi#12345 #12345"; Issue notMatchIssue = createIssue(testOwner, testProject, "hello", notMatchBody); // When String body = "_" + testOwner.loginId + "#" + notMatchIssue.getNumber() + "-\n" + "A" + testOwner.loginId + "#" + notMatchIssue.getNumber() + "AA\n"; Issue issue = createIssue(testOwner, testProject, "hello", body); Result result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(issue.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).doesNotContain(RouteUtil.getUrl(notMatchIssue)); } @Test public void test_issueNumber() { /** * Supported case * 1. User/#Num nforge#12345 * 2. User/Project#Num nforge/yobi#12345 * 3. #Num #123 */ // When not match String notMatchBody = "nforge#12345 nforge/yobi#12345 #12345"; Issue notMatchIssue = createIssue(testOwner, testProject, "hello", notMatchBody); Result result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(notMatchIssue.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(notMatchBody); // When User/#Num nforge#12345 String matchBody1 = testOwner.loginId + "#" + notMatchIssue.getNumber(); Issue matchIssue1 = createIssue(testOwner, testProject, "hello", matchBody1); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue1.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(RouteUtil.getUrl(notMatchIssue)); // When User/#Num nforge/yobi#12345 String matchBody2 = anotherProject.toString() + "#" + anotherIssue.getNumber(); Issue matchIssue2 = createIssue(testOwner, testProject, "hello", matchBody2); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue2.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(RouteUtil.getUrl(anotherIssue)); // When #Num #12345 String matchBody3 = "#" + notMatchIssue.getNumber(); Issue matchIssue3 = createIssue(testOwner, testProject, "hello", matchBody3); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue3.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(RouteUtil.getUrl(notMatchIssue)); } @Test public void test_SHA() throws IOException, GitAPIException { // Given RevCommit commit = createCommit(createRepository(testProject), testOwner, testProject); RevCommit anotherCommit = createCommit(createRepository(anotherProject), anotherOwner, anotherProject); /** * Supported case * 1. SHA be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 * 2. @SHA @be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 * 3. User@SHA nforge@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 * 4. User/Project@SHA nforge/yobi@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 */ // When not match String notMatchBody = "@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 " + "@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 " + "nforge@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 " + "nforge/yobi@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2"; Issue notMatchIssue = createIssue(testOwner, testProject, "hello", notMatchBody); Result result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(notMatchIssue.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(notMatchBody); // When SHA be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 String matchBody1 = commit.getId().name(); Issue matchIssue1 = createIssue(testOwner, testProject, "hello", matchBody1); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue1.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(getCommitUrl(commit, testProject)); // When SHA @be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 String matchBody2 = "@" + commit.getId().name(); Issue matchIssue2 = createIssue(testOwner, testProject, "hello", matchBody2); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue2.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(getCommitUrl(commit, testProject)); // When User@SHA nforge@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 String matchBody3 = testOwner.loginId + "@" + commit.getId().name(); Issue matchIssue3 = createIssue(testOwner, testProject, "hello", matchBody3); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue3.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(getCommitUrl(commit, testProject)); // When User/Project@SHA nforge/yobi@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2 String matchBody4 = anotherProject.toString() + "@" + anotherCommit.getId().name(); Issue matchIssue4 = createIssue(testOwner, testProject, "hello", matchBody4); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue4.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(getCommitUrl(anotherCommit, anotherProject)); } @Test public void testMention() { /** * Supported case * 1. @User @nforge * 2. @User/Project @nforge/yobi */ // When not match String notMatchBody = "@nforge @nforge/yobi"; Issue notMatchIssue = createIssue(testOwner, testProject, "hello", notMatchBody); Result result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(notMatchIssue.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(notMatchBody); // When @User @nforge String matchBody1 = "@" + testOwner.loginId; Issue matchIssue1 = createIssue(testOwner, testProject, "hello", matchBody1); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue1.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(RouteUtil.getUrl(testOwner)); // When @User/nforge String matchBody2 = "@" + testProject.toString(); Issue matchIssue2 = createIssue(testOwner, testProject, "hello", matchBody2); result = callAction( controllers.routes.ref.MarkdownApp.render(testProject.owner, testProject.name), makeFakeRequest(matchIssue2.getBody()) ); // Then assertThat(status(result)).isEqualTo(OK); assertThat(contentAsString(result)).contains(RouteUtil.getUrl(testProject)); } }