Suwon Chae 2014-08-04
test: refactoring which is aimed for testing time and efficiency
@85ca03e511afe3d788aced7571860668dc57d605
app/models/PullRequest.java
--- app/models/PullRequest.java
+++ app/models/PullRequest.java
@@ -935,4 +935,9 @@
                 this.mergedCommitIdFrom != null && this.mergedCommitIdTo != null;
     }
 
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        PullRequest cloned = (PullRequest)super.clone();
+        return cloned;
+    }
 }
app/utils/PasswordReset.java
--- app/utils/PasswordReset.java
+++ app/utils/PasswordReset.java
@@ -48,20 +48,16 @@
     }
 
     public static void addHashToResetTable(String userId, String hashString) {
-        Logger.debug(">> add to HashTable " + userId + ":" + hashString);
         PasswordReset.resetHashMap.put(userId, hashString);
         resetHashTimetable.put(hashString, new DateTime().getMillis());
     }
 
     public static boolean isValidResetHash(String hashString) {
-        Logger.debug("Reset hash entry size:" + resetHashMap.size());
         if( !resetHashMap.containsValue(hashString) ) {
-            Logger.debug("HashString doesn't exists in resetHashMap: " + hashString);
             return false;
         }
 
         if(isExpired(hashString)) {
-            Logger.debug("HashString was expired: " + hashString);
             return false;
         }
 
conf/test-data.yml
--- conf/test-data.yml
+++ conf/test-data.yml
@@ -24,6 +24,7 @@
         state:          ACTIVE
         email:          doortts@gmail.com
         createdDate:           2012-07-01 08:00:00
+        state: ACTIVE
     - !!models.User
         name:           eungjun
         loginId:        nori
project/Build.scala
--- project/Build.scala
+++ project/Build.scala
@@ -1,5 +1,5 @@
 import sbt._
-import Keys._
+import sbt.Keys._
 import play.Project.javaCore
 import play.Project.javaJdbc
 import play.Project.javaEbean
@@ -65,7 +65,7 @@
       templatesImport += "models.enumeration._",
       lessEntryPoints <<= baseDirectory(_ / "app" / "assets" / "stylesheets" ** "yobi.less"),
         //      jacoco.settings:_*,
-      javaOptions in test ++= Seq("-Xmx512m", "-XX:MaxPermSize=512m", "-Dfile.encoding=UTF-8"),
+      javaOptions in test ++= Seq("-Xmx2g", "-Xms1g", "-XX:MaxPermSize=1g", "-Dfile.encoding=UTF-8"),
       javacOptions ++= Seq("-Xlint:all", "-Xlint:-path"),
       scalacOptions ++= Seq("-feature")
     )
test/controllers/CommentAppTest.java
--- test/controllers/CommentAppTest.java
+++ test/controllers/CommentAppTest.java
@@ -56,13 +56,12 @@
         callAction(
                 routes.ref.Application.init()
         );
+        app = support.Helpers.makeTestApplication();
+        Helpers.start(app);
     }
 
     @Before
     public void before() {
-        app = support.Helpers.makeTestApplication();
-        Helpers.start(app);
-
         admin = User.findByLoginId("admin");
         manager = User.findByLoginId("yobi");
         member = User.findByLoginId("laziel");
test/controllers/EnrollProjectAppTest.java
--- test/controllers/EnrollProjectAppTest.java
+++ test/controllers/EnrollProjectAppTest.java
@@ -33,16 +33,16 @@
 import play.test.FakeApplication;
 
 public class EnrollProjectAppTest {
-    private FakeApplication application;
+    private static FakeApplication application;
 
-    @Before
-    public void before() {
+    @BeforeClass
+    public static void beforeClass() {
         application = support.Helpers.makeTestApplication();
         start(application);
     }
 
-    @After
-    public void after() {
+    @AfterClass
+    public static void afterClass() {
         stop(application);
     }
 
test/controllers/ImportAppTest.java
--- test/controllers/ImportAppTest.java
+++ test/controllers/ImportAppTest.java
@@ -31,9 +31,7 @@
 import models.Project;
 import models.User;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
 
 import controllers.routes.ref;
 
@@ -46,14 +44,14 @@
 import utils.Constants;
 
 public class ImportAppTest {
-    private FakeApplication application;
-    private User yobi;
-    private Project src;
-    private Project dest;
-    private Map<String, String> formData;
+    private static FakeApplication application;
+    private static User yobi;
+    private static Project src;
+    private static Project dest;
+    private static Map<String, String> formData;
 
-    @Before
-    public void before() throws Exception {
+    @BeforeClass
+    public static void before() throws Exception {
         GitRepository.setRepoPrefix("resources/test/repo/git/");
         GitRepository.setRepoForMergingPrefix("resources/test/repo/git-merging/");
         application = support.Helpers.makeTestApplication();
@@ -65,8 +63,8 @@
         formData = new HashMap<>();
     }
 
-    @After
-    public void after() {
+    @AfterClass
+    public static void after() {
         stop(application);
         support.Files.rm_rf(new File(GitRepository.getRepoPrefix()));
         support.Files.rm_rf(new File(GitRepository.getRepoForMergingPrefix()));
@@ -191,14 +189,14 @@
         assertThat(contentAsString(result)).contains(Messages.get(Lang.defaultLang(), "project.name.alert"));
     }
 
-    private Project project(String owner, String name) {
+    private static Project project(String owner, String name) {
         Project project = new Project();
         project.owner = owner;
         project.name = name;
         return project;
     }
 
-    private void createRepository(Project project) throws Exception {
+    private static void createRepository(Project project) throws Exception {
         GitRepository gitRepository = new GitRepository(project);
         gitRepository.create();
         gitRepository.close();
test/controllers/ProjectAppTest.java
--- test/controllers/ProjectAppTest.java
+++ test/controllers/ProjectAppTest.java
@@ -67,11 +67,6 @@
         Helpers.start(app);
     }
 
-    @After
-    public void after() {
-        Helpers.stop(app);
-    }
-
     @Test
     public void label() {
         //Given
test/controllers/PullRequestAppTest.java
--- test/controllers/PullRequestAppTest.java
+++ test/controllers/PullRequestAppTest.java
@@ -40,22 +40,52 @@
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.RefSpec;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.*;
 
+import org.junit.rules.TestWatcher;
 import play.mvc.Result;
 import play.test.FakeApplication;
 import play.test.Helpers;
+import support.ExecutionTimeWatcher;
 import playRepository.GitRepository;
 
 public class PullRequestAppTest {
-    protected FakeApplication app;
+    protected static FakeApplication app;
 
     private String ownerLoginId;
     private String projectName;
     private Long pullRequestNumber;
+    private static PullRequest pullRequest;
+    private static boolean isInit = false;
+
+    @Rule
+    public TestWatcher watcher = new ExecutionTimeWatcher();
+
+    @BeforeClass
+    public static void beforeClass() {
+        callAction(
+                routes.ref.Application.init()
+        );
+        app = support.Helpers.makeTestApplication();
+        Helpers.start(app);
+    }
+
+    @Before
+    public void before() {
+        GitRepository.setRepoPrefix("resources/test/repo/git/");
+        GitRepository.setRepoForMergingPrefix("resources/test/repo/git-merging/");
+    }
+
+    @AfterClass
+    public static void afterClase(){
+        Helpers.stop(app);
+    }
+
+    @After
+    public void after() {
+        support.Files.rm_rf(new File(GitRepository.getRepoPrefix()));
+        support.Files.rm_rf(new File(GitRepository.getRepoForMergingPrefix()));
+    }
 
     @Test
     public void testCloseAnonymous() throws Exception {
@@ -103,8 +133,8 @@
         Result result = callAction(
                 controllers.routes.ref.PullRequestApp.close(ownerLoginId, projectName, pullRequestNumber),
                 fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/pullRequest/" + pullRequestNumber)
-                .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
-              );
+                        .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
+        );
 
         assertThat(status(result)).isEqualTo(SEE_OTHER);
         assertThat(PullRequest.findById(pullRequestNumber).state).isEqualTo(State.CLOSED);
@@ -114,6 +144,13 @@
     public void testClosePullRequestNotAllow() throws Exception {
         initParameters("yobi", "projectYobi", 1L);
         User currentUser = User.findByLoginId("alecsiel");
+        User projectOwner = User.findByLoginId("yobi");
+
+        callAction(
+                controllers.routes.ref.PullRequestApp.open(ownerLoginId, projectName, pullRequestNumber),
+                fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/pullRequest/" + pullRequestNumber)
+                        .withSession(UserApp.SESSION_USERID, projectOwner.id.toString())
+        );
 
         Result result = callAction(
                 controllers.routes.ref.PullRequestApp.close(ownerLoginId, projectName, pullRequestNumber),
@@ -222,8 +259,8 @@
         Result result = callAction(
                 controllers.routes.ref.PullRequestApp.newFork(ownerLoginId, projectName, null),
                 fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/newFork")
-                .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
-              );
+                        .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
+        );
 
         assertThat(status(result)).isEqualTo(OK);
     }
@@ -236,8 +273,8 @@
         Result result = callAction(
                 controllers.routes.ref.PullRequestApp.newFork(ownerLoginId, projectName, null),
                 fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/newFork")
-                .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
-              );
+                        .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
+        );
 
         assertThat(status(result)).isEqualTo(FORBIDDEN);
     }
@@ -255,9 +292,9 @@
         Result result = callAction(
                 controllers.routes.ref.PullRequestApp.fork(ownerLoginId, projectName),
                 fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/fork")
-                .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
-                .withFormUrlEncodedBody(data)
-              );
+                        .withSession(UserApp.SESSION_USERID, currentUser.id.toString())
+                        .withFormUrlEncodedBody(data)
+        );
 
         assertThat(status(result)).isEqualTo(OK);
     }
@@ -310,41 +347,30 @@
 
     @Test
     public void testOpenRoute() throws Exception {
+        //Given
         initParameters("yobi", "projectYobi", 1L);
-        String url = "/" + ownerLoginId + "/" + projectName + "/pullRequest/" + pullRequestNumber + "/open";
         User currentUser = User.findByLoginId("yobi");
+        User projectOwner = User.findByLoginId("yobi");
 
+        String url = "/" + ownerLoginId + "/" + projectName + "/pullRequest/" + pullRequestNumber + "/open";
+        callAction(
+                controllers.routes.ref.PullRequestApp.open(ownerLoginId, projectName, pullRequestNumber),
+                fakeRequest("GET", "/" + ownerLoginId + "/" + projectName + "/pullRequest/" + pullRequestNumber)
+                        .withSession(UserApp.SESSION_USERID, projectOwner.id.toString())
+        );
+
+        //When
         Result result = route(
             fakeRequest(POST, url).withSession(UserApp.SESSION_USERID, currentUser.id.toString())
         );
+
+        //Then
         assertThat(status(result)).isEqualTo(BAD_REQUEST);
 
         Project project = Project.findByOwnerAndProjectName(ownerLoginId, projectName);
         PullRequest pullRequest = PullRequest.findOne(project, pullRequestNumber);
 
         assertThat(pullRequest.state).isEqualTo(State.OPEN);
-    }
-
-    @BeforeClass
-    public static void beforeClass() {
-        callAction(
-                routes.ref.Application.init()
-        );
-    }
-
-    @Before
-    public void before() {
-        GitRepository.setRepoPrefix("resources/test/repo/git/");
-        GitRepository.setRepoForMergingPrefix("resources/test/repo/git-merging/");
-        app = support.Helpers.makeTestApplication();
-        Helpers.start(app);
-    }
-
-    @After
-    public void after() {
-        Helpers.stop(app);
-        support.Files.rm_rf(new File(GitRepository.getRepoPrefix()));
-        support.Files.rm_rf(new File(GitRepository.getRepoForMergingPrefix()));
     }
 
     private void initParameters(String ownerLoginId, String projectName, Long pullRequestNumber)
test/controllers/ReviewThreadAppTest.java
--- test/controllers/ReviewThreadAppTest.java
+++ test/controllers/ReviewThreadAppTest.java
@@ -35,6 +35,20 @@
     protected static FakeApplication app;
 
     /**
+     * 테스트를 위해 메모리 DB로 전환
+     */
+    @BeforeClass
+    public static void beforeClass() {
+        app = support.Helpers.makeTestApplication();
+        Helpers.start(app);
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        Helpers.stop(app);
+    }
+
+    /**
      * 잘못된 URL을 입력하여 not found return을 테스트
      */
     @Test
@@ -57,19 +71,5 @@
         );
 
         assertThat(status(result)).isEqualTo(SEE_OTHER);
-    }
-
-    /**
-     * 테스트를 위해 메모리 DB로 전환
-     */
-    @BeforeClass
-    public static void beforeClass() {
-        app = support.Helpers.makeTestApplication();
-        Helpers.start(app);
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        Helpers.stop(app);
     }
 }
 
test/controllers/SearchAppTest.java (deleted)
--- test/controllers/SearchAppTest.java
@@ -1,35 +0,0 @@
-/**
- * Yobi, Project Hosting SW
- *
- * Copyright 2012 NAVER Corp.
- * http://yobi.io
- *
- * @Author Suwon Chae
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package controllers;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class SearchAppTest {
-    @Test
-    @Ignore
-    public void testContentsSearch_fromTitle() {
-    }
-
-    @Test @Ignore
-    public void findById() {
-    }
-}
test/controllers/SiteAppTest.java
--- test/controllers/SiteAppTest.java
+++ test/controllers/SiteAppTest.java
@@ -23,6 +23,7 @@
 import models.*;
 import models.enumeration.UserState;
 import org.junit.*;
+import play.mvc.Result;
 import play.test.FakeApplication;
 import play.test.Helpers;
 
@@ -30,52 +31,46 @@
 import java.util.Map;
 
 import static org.fest.assertions.Assertions.assertThat;
-import static play.test.Helpers.callAction;
-import static play.test.Helpers.fakeRequest;
+import static play.test.Helpers.*;
 
 public class SiteAppTest {
     protected static FakeApplication app;
-    private User admin;
-    private User notAdmin;
 
     @BeforeClass
     public static void beforeClass() {
         callAction(
                 routes.ref.Application.init()
         );
-    }
-
-    @Before
-    public void before() {
-        Map<String, String> config = support.Helpers.makeTestConfig();
-        config.put("signup.require.confirm", "true");
-        app = support.Helpers.makeTestApplication(config);
+        app = support.Helpers.makeTestApplication();
         Helpers.start(app);
     }
 
-    @After
-    public void after() {
+    @AfterClass
+    public static void afterClass() {
         Helpers.stop(app);
     }
 
-    @Test @Ignore   //FixMe I don't know how to make a assert
+
+    @Test
     public void testToggleUserAccountLock() {
         //Given
         Map<String,String> data = new HashMap<>();
         final String loginId= "doortts";
         data.put("loginId", loginId);
+        User admin = User.find.byId(1L);
 
-        User targetUser = User.findByLoginId(loginId);
-        UserState currentIsLocked = targetUser.state;
-
+        System.out.println(User.findByLoginId(loginId).state);
         //When
-        callAction(
+
+        Result result = callAction(
                 controllers.routes.ref.SiteApp.toggleAccountLock(loginId, "", ""),
-                fakeRequest()
+                fakeRequest(POST, routes.SiteApp.toggleAccountLock(loginId, "", "").url())
                         .withFormUrlEncodedBody(data)
-                        .withSession("loginId", "admin")
-        );
+                        .withSession("loginId", admin.loginId)
+                        .withSession(UserApp.SESSION_USERID, admin.id.toString()));
         //Then
-        assertThat(User.findByLoginId(loginId).state).isNotEqualTo(currentIsLocked);
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(flash(result)).isEmpty();
+        assertThat(User.findByLoginId(loginId).state).isEqualTo(UserState.LOCKED);
     }
 }
test/controllers/UserAppTest.java
--- test/controllers/UserAppTest.java
+++ test/controllers/UserAppTest.java
@@ -27,8 +27,12 @@
 
 import java.util.*;
 
+import org.junit.rules.TestWatcher;
 import play.mvc.*;
 import play.mvc.Http.*;
+import play.test.FakeApplication;
+import play.test.Helpers;
+import support.ExecutionTimeWatcher;
 import support.ContextTest;
 import utils.JodaDateUtil;
 
@@ -38,528 +42,417 @@
 import static org.mockito.Mockito.*;
 
 public class UserAppTest extends ContextTest {
+    protected static FakeApplication app;
+
+    @Rule
+    public TestWatcher watcher = new ExecutionTimeWatcher();
+
     @BeforeClass
     public static void beforeClass() {
         callAction(
                 routes.ref.Application.init()
         );
+        Map<String, String> config = support.Helpers.makeTestConfig();
+        config.put("signup.require.confirm", "true");
+
+        app = support.Helpers.makeTestApplication(config);
+        Helpers.start(app);
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        Helpers.stop(app);
     }
 
     @Test
     public void findById_doesntExist() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                Map<String,String> data = new HashMap<>();
-                data.put("loginId", "nekure");
+        //Given
+        Map<String,String> data = new HashMap<>();
+        data.put("loginId", "nekure");
 
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.isUsed("nekure"),
-                        fakeRequest().withFormUrlEncodedBody(data)
-                );  // fakeRequest doesn't need here, but remains for example
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.isUsed("nekure"),
+                fakeRequest().withFormUrlEncodedBody(data)
+        );  // fakeRequest doesn't need here, but remains for example
 
-                //Then
-                assertThat(status(result)).isEqualTo(OK);
-                assertThat(contentAsString(result)).contains("\"isExist\":false");
-                assertThat(contentType(result)).contains("json");
-            }
-        });
+        //Then
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(contentAsString(result)).contains("\"isExist\":false");
+        assertThat(contentType(result)).contains("json");
     }
 
     @Test
     public void findById_alreadyExist() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                Map<String,String> data = new HashMap<>();
-                data.put("loginId", "yobi");
+        //Given
+        Map<String,String> data = new HashMap<>();
+        data.put("loginId", "yobi");
 
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.isUsed("yobi"),
-                        fakeRequest().withFormUrlEncodedBody(data)
-                ); // fakeRequest doesn't need here, but remains for example
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.isUsed("yobi"),
+                fakeRequest().withFormUrlEncodedBody(data)
+        ); // fakeRequest doesn't need here, but remains for example
 
-                //Then
-                assertThat(status(result)).isEqualTo(OK);
-                assertThat(contentAsString(result)).contains("\"isExist\":true");
-                assertThat(contentType(result)).contains("json");
-            }
-        });
+        //Then
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(contentAsString(result)).contains("\"isExist\":true");
+        assertThat(contentType(result)).contains("json");
     }
 
     @Test
     public void findById_alreadyExistGroupName() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                String loginId = "labs";
+        //Given
+        String loginId = "labs";
 
-                //When
-                Result result = callAction(controllers.routes.ref.UserApp.isUsed(loginId));
+        //When
+        Result result = callAction(controllers.routes.ref.UserApp.isUsed(loginId));
 
-                //Then
-                assertThat(status(result)).isEqualTo(OK);
-                assertThat(contentAsString(result)).contains("\"isExist\":true");
-                assertThat(contentType(result)).contains("json");
-            }
-        });
+        //Then
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(contentAsString(result)).contains("\"isExist\":true");
+        assertThat(contentType(result)).contains("json");
     }
 
     @Test
     public void isEmailExist() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.isEmailExist("doortts@gmail.com")
-                );
+        //Given
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.isEmailExist("doortts@gmail.com")
+        );
 
-                //Then
-                assertThat(status(result)).isEqualTo(OK);
-                assertThat(contentAsString(result)).contains("{\"isExist\":true}");
-            }
-        });
+        //Then
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(contentAsString(result)).contains("{\"isExist\":true}");
     }
 
     @Test
     public void login_notComfirmedUser() {
-        Map<String, String> config = support.Helpers.makeTestConfig();
-        config.put("signup.require.confirm", "true");
+        //Given
+        User user = new User(-31l);
+        user.loginId = "fakeUser";
+        user.email = "fakeuser@fake.com";
+        user.name = "racoon";
+        user.password = "somefakepassword";
+        user.createdDate = JodaDateUtil.now();
+        user.state = UserState.LOCKED;
+        user.save();
 
-        running(support.Helpers.makeTestApplication(config), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                User user = new User(-31l);
-                user.loginId = "fakeUser";
-                user.email = "fakeuser@fake.com";
-                user.name = "racoon";
-                user.password = "somefakepassword";
-                user.createdDate = JodaDateUtil.now();
-                user.state = UserState.LOCKED;
-                user.save();
+        Map<String, String> data = new HashMap<>();
+        data.put("loginIdOrEmail", user.loginId);
+        data.put("password", user.password);
 
-                Map<String, String> data = new HashMap<>();
-                data.put("loginIdOrEmail", user.loginId);
-                data.put("password", user.password);
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.login(),
+                fakeRequest().withFormUrlEncodedBody(data)
+        );
 
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.login(),
-                        fakeRequest().withFormUrlEncodedBody(data)
-                );
-
-                //Then
-                assertThat(status(result)).describedAs("result status should '303 see other'").isEqualTo(303);
-            }
-        });
+        //Then
+        assertThat(status(result)).describedAs("result status should '303 see other'").isEqualTo(303);
     }
 
     @Test
     public void newUser_AlreadyExistGroupName() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                Map<String, String> data = new HashMap<>();
-                data.put("loginId", "labs");
-                data.put("password", "somefakepassword");
-                data.put("email", "labs@fake.com");
-                data.put("name", "labs");
+        //Given
+        Map<String, String> data = new HashMap<>();
+        data.put("loginId", "labs");
+        data.put("password", "somefakepassword");
+        data.put("email", "labs@fake.com");
+        data.put("name", "labs");
 
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.newUser(),
-                        fakeRequest().withFormUrlEncodedBody(data)
-                );
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.newUser(),
+                fakeRequest().withFormUrlEncodedBody(data)
+        );
 
-                //Then
-                assertThat(status(result)).describedAs("result status should '400 bad request'").isEqualTo(BAD_REQUEST);
-            }
-        });
+        //Then
+        assertThat(status(result)).describedAs("result status should '400 bad request'").isEqualTo(BAD_REQUEST);
     }
 
     @Test
     public void newUser_confirmSignUpMode() {
-        Map<String, String> config = support.Helpers.makeTestConfig();
-        config.put("signup.require.confirm", "true");
+        //Given
+        final String loginId = "somefakeuserid";
+        Map<String, String> data = new HashMap<>();
+        data.put("loginId", loginId);
+        data.put("password", "somefakepassword");
+        data.put("email", "somefakeuserid@fake.com");
+        data.put("name", "racoon");
 
-        running(support.Helpers.makeTestApplication(config), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                final String loginId = "somefakeuserid";
-                Map<String, String> data = new HashMap<>();
-                data.put("loginId", loginId);
-                data.put("password", "somefakepassword");
-                data.put("email", "fakeuser@fake.com");
-                data.put("name", "racoon");
+        //When
+        Result result = callAction(
+                controllers.routes.ref.UserApp.newUser(),
+                fakeRequest().withFormUrlEncodedBody(data)
+        );
 
-                //When
-                Result result = callAction(
-                        controllers.routes.ref.UserApp.newUser(),
-                        fakeRequest().withFormUrlEncodedBody(data)
-                );
-
-                //Then
-                assertThat(status(result)).describedAs("result status should '303 see other'").isEqualTo(303);
-            }
-        });
+        //Then
+        assertThat(status(result)).describedAs("result status should '303 see other'").isEqualTo(303);
     }
 
     @Test
     public void findById_reserved() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                //Given
-                Map<String,String> data = new HashMap<>();
-                data.put("loginId", "messages.js");
+        //Given
+        Map<String,String> data = new HashMap<>();
+        data.put("loginId", "messages.js");
 
-                //When
-                Result result = callAction(controllers.routes.ref.UserApp.isUsed("messages.js"));
+        //When
+        Result result = callAction(controllers.routes.ref.UserApp.isUsed("messages.js"));
 
-                //Then
-                assertThat(status(result)).isEqualTo(OK);
-                assertThat(contentAsString(result)).contains("\"isReserved\":true");
-                assertThat(contentType(result)).contains("json");
-            }
-        });
+        //Then
+        assertThat(status(result)).isEqualTo(OK);
+        assertThat(contentAsString(result)).contains("\"isReserved\":true");
+        assertThat(contentType(result)).contains("json");
     }
 
     @Test
     public void authenticateWithPlainPassword() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "pass";
+        // Given
+        String loginId = "kjkmadness";
+        String password = "pass";
 
-                // When
-                User user = UserApp.authenticateWithPlainPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithPlainPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isFalse();
-                assertThat(user.loginId).isEqualTo(loginId);
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isFalse();
+        assertThat(user.loginId).isEqualTo(loginId);
     }
 
     @Test
     public void authenticateWithPlainPasswordWrongPassword() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "wrong";
+        // Given
+        String loginId = "kjkmadness";
+        String password = "wrong";
 
-                // When
-                User user = UserApp.authenticateWithPlainPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithPlainPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isTrue();
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isTrue();
     }
 
     @Test
     public void authenticateWithPlainPasswordNotExist() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "notexist";
-                String password = "pass";
+        // Given
+        String loginId = "notexist";
+        String password = "pass";
 
-                // When
-                User user = UserApp.authenticateWithPlainPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithPlainPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isTrue();
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isTrue();
     }
 
     @Test
     public void authenticateWithHashedPassword() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
+        // Given
+        String loginId = "kjkmadness";
+        String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
 
-                // When
-                User user = UserApp.authenticateWithHashedPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithHashedPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isFalse();
-                assertThat(user.loginId).isEqualTo(loginId);
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isFalse();
+        assertThat(user.loginId).isEqualTo(loginId);
     }
 
     @Test
     public void authenticateWithHashedPasswordWrongPassword() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "wrong";
+        // Given
+        String loginId = "kjkmadness";
+        String password = "wrong";
 
-                // When
-                User user = UserApp.authenticateWithHashedPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithHashedPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isTrue();
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isTrue();
     }
 
     @Test
     public void authenticateWithHashedPasswordNotExist() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "notexist";
-                String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
+        // Given
+        String loginId = "notexist";
+        String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
 
-                // When
-                User user = UserApp.authenticateWithHashedPassword(loginId, password);
+        // When
+        User user = UserApp.authenticateWithHashedPassword(loginId, password);
 
-                // Then
-                assertThat(user).isNotNull();
-                assertThat(user.isAnonymous()).isTrue();
-            }
-        });
+        // Then
+        assertThat(user).isNotNull();
+        assertThat(user.isAnonymous()).isTrue();
     }
 
     @Test
     public void login() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "pass";
-                User user = User.findByLoginId(loginId);
-                Map<String, String> data = new HashMap<>();
-                data.put("loginIdOrEmail", loginId);
-                data.put("password", password);
+        // Given
+        String loginId = "kjkmadness";
+        String password = "pass";
+        User user = User.findByLoginId(loginId);
+        Map<String, String> data = new HashMap<>();
+        data.put("loginIdOrEmail", loginId);
+        data.put("password", password);
 
-                // When
-                Result result = callAction(controllers.routes.ref.UserApp.login(), fakeRequest()
-                        .withFormUrlEncodedBody(data));
+        // When
+        Result result = callAction(controllers.routes.ref.UserApp.login(), fakeRequest()
+                .withFormUrlEncodedBody(data));
 
-                // Then
-                assertThat(status(result)).isEqualTo(SEE_OTHER);
-                assertThat(header(LOCATION, result)).isEqualTo(routes.Application.index().url());
-                assertThat(session(result)).includes(
-                        entry(UserApp.SESSION_USERID, String.valueOf(user.id)),
-                        entry(UserApp.SESSION_LOGINID, user.loginId),
-                        entry(UserApp.SESSION_USERNAME, user.name));
-            }
-        });
+        // Then
+        assertThat(status(result)).isEqualTo(SEE_OTHER);
+        assertThat(header(LOCATION, result)).isEqualTo(routes.Application.index().url());
+        assertThat(session(result)).includes(
+                entry(UserApp.SESSION_USERID, String.valueOf(user.id)),
+                entry(UserApp.SESSION_LOGINID, user.loginId),
+                entry(UserApp.SESSION_USERNAME, user.name));
     }
 
     @Test
     public void loginWrongPassword() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "wrong";
-                Map<String, String> data = new HashMap<>();
-                data.put("loginIdOrEmail", loginId);
-                data.put("password", password);
+        // Given
+        String loginId = "kjkmadness";
+        String password = "wrong";
+        Map<String, String> data = new HashMap<>();
+        data.put("loginIdOrEmail", loginId);
+        data.put("password", password);
 
-                // When
-                Result result = callAction(controllers.routes.ref.UserApp.login(), fakeRequest()
-                        .withFormUrlEncodedBody(data));
+        // When
+        Result result = callAction(controllers.routes.ref.UserApp.login(), fakeRequest()
+                .withFormUrlEncodedBody(data));
 
-                // Then
-                assertThat(status(result)).isEqualTo(SEE_OTHER);
-                assertThat(header(LOCATION, result)).isEqualTo(routes.UserApp.loginForm().url());
-                assertThat(session(result)).isEmpty();
-            }
-        });
+        // Then
+        assertThat(status(result)).isEqualTo(SEE_OTHER);
+        assertThat(header(LOCATION, result)).isEqualTo(routes.UserApp.loginForm().url());
+        assertThat(session(result)).isEmpty();
     }
 
     @Test
     public void currentUserContext() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                User expected = User.find.byId(1L);
-                context().withArg(UserApp.TOKEN_USER, expected);
+        // Given
+        User expected = User.find.byId(1L);
+        context().withArg(UserApp.TOKEN_USER, expected);
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(expected);
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(expected);
     }
 
     @Test
     public void currentUserSession() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                Long id = 1L;
-                context().withSession(UserApp.SESSION_USERID, String.valueOf(id));
+        // Given
+        Long id = 1L;
+        context().withSession(UserApp.SESSION_USERID, String.valueOf(id));
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isNotEqualTo(User.anonymous);
-                assertThat(user.id).isEqualTo(id);
-            }
-        });
+        // Then
+        assertThat(user).isNotEqualTo(User.anonymous);
+        assertThat(user.id).isEqualTo(id);
     }
 
     @Test
     public void currentUserSessionNotNumeric() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                Context context = context().withSession(UserApp.SESSION_USERID, "string");
+        // Given
+        Context context = context().withSession(UserApp.SESSION_USERID, "string");
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(User.anonymous);
-                assertThat(context.session()).isEmpty();
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(User.anonymous);
+        assertThat(context.session()).isEmpty();
     }
 
     @Test
     public void currentUserSessionNoUser() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                Context context = context().withSession(UserApp.SESSION_USERID, "0");
+        // Given
+        Context context = context().withSession(UserApp.SESSION_USERID, "0");
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(User.anonymous);
-                assertThat(context.session()).isEmpty();
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(User.anonymous);
+        assertThat(context.session()).isEmpty();
     }
 
     @Test
     public void currentUserToken() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
-                String token = loginId + UserApp.TOKEN_SEPARATOR + password;
-                Context context = context().withCookie(UserApp.TOKEN, token);
+        // Given
+        String loginId = "kjkmadness";
+        String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
+        String token = loginId + UserApp.TOKEN_SEPARATOR + password;
+        Context context = context().withCookie(UserApp.TOKEN, token);
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isNotEqualTo(User.anonymous);
-                assertThat(user.loginId).isEqualTo(loginId);
-                assertThat(context.session()).includes(
-                        entry(UserApp.SESSION_USERID, String.valueOf(user.id)),
-                        entry(UserApp.SESSION_LOGINID, user.loginId),
-                        entry(UserApp.SESSION_USERNAME, user.name));
-            }
-        });
+        // Then
+        assertThat(user).isNotEqualTo(User.anonymous);
+        assertThat(user.loginId).isEqualTo(loginId);
+        assertThat(context.session()).includes(
+                entry(UserApp.SESSION_USERID, String.valueOf(user.id)),
+                entry(UserApp.SESSION_LOGINID, user.loginId),
+                entry(UserApp.SESSION_USERNAME, user.name));
     }
 
     @Test
     public void currentUserTokenInvalidLength() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
-                String token = loginId + UserApp.TOKEN_SEPARATOR + password
-                        + UserApp.TOKEN_SEPARATOR + "dummy";
-                Context context = context().withCookie(UserApp.TOKEN, token);
+        // Given
+        String loginId = "kjkmadness";
+        String password = "ckJUVVaOHhRDNqwbeF+j4RNqXzodXO95+aQRIbJnDK4=";
+        String token = loginId + UserApp.TOKEN_SEPARATOR + password
+                + UserApp.TOKEN_SEPARATOR + "dummy";
+        Context context = context().withCookie(UserApp.TOKEN, token);
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(User.anonymous);
-                assertThat(context.session()).isEmpty();
-                verify(context.response()).discardCookie(UserApp.TOKEN);
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(User.anonymous);
+        assertThat(context.session()).isEmpty();
+        verify(context.response()).discardCookie(UserApp.TOKEN);
     }
 
     @Test
     public void currentUserTokenNoUser() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                String loginId = "kjkmadness";
-                String password = "dummy";
-                String token = loginId + UserApp.TOKEN_SEPARATOR + password;
-                Context context = context().withCookie(UserApp.TOKEN, token);
+        // Given
+        String loginId = "kjkmadness";
+        String password = "dummy";
+        String token = loginId + UserApp.TOKEN_SEPARATOR + password;
+        Context context = context().withCookie(UserApp.TOKEN, token);
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(User.anonymous);
-                assertThat(context.session()).isEmpty();
-                verify(context.response()).discardCookie(UserApp.TOKEN);
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(User.anonymous);
+        assertThat(context.session()).isEmpty();
+        verify(context.response()).discardCookie(UserApp.TOKEN);
     }
 
     @Test
     public void currentUserAnonymous() {
-        running(support.Helpers.makeTestApplication(), new Runnable() {
-            @Override
-            public void run() {
-                // Given
-                Context context = context();
+        // Given
+        Context context = context();
 
-                // When
-                User user = UserApp.currentUser();
+        // When
+        User user = UserApp.currentUser();
 
-                // Then
-                assertThat(user).isEqualTo(User.anonymous);
-                assertThat(context.session()).isEmpty();
-            }
-        });
+        // Then
+        assertThat(user).isEqualTo(User.anonymous);
+        assertThat(context.session()).isEmpty();
     }
 }
test/controllers/WatchProjectAppTest.java
--- test/controllers/WatchProjectAppTest.java
+++ test/controllers/WatchProjectAppTest.java
@@ -31,27 +31,32 @@
 import models.enumeration.EventType;
 import models.enumeration.ProjectScope;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
 
 import play.mvc.Http;
 import play.mvc.Result;
 import play.test.FakeApplication;
 import play.test.FakeRequest;
+import play.test.Helpers;
+
+import java.util.Map;
 
 public class WatchProjectAppTest {
-    private static FakeApplication app;
+    protected static FakeApplication app;
 
-    @Before
-    public void before() {
+    @BeforeClass
+    public static void beforeClass() {
+        callAction(
+                routes.ref.Application.init()
+        );
+
         app = support.Helpers.makeTestApplication();
-        start(app);
+        Helpers.start(app);
     }
 
-    @After
-    public void after() {
-        stop(app);
+    @AfterClass
+    public static void afterClass() {
+        Helpers.stop(app);
     }
 
     @Test
test/models/ModelTest.java
--- test/models/ModelTest.java
+++ test/models/ModelTest.java
@@ -21,7 +21,9 @@
 package models;
 
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import play.test.FakeApplication;
 import play.test.Helpers;
 //import support.EbeanUtil;
@@ -36,7 +38,7 @@
     }
 
     @Before
-    public void startApp() {
+    public  void startApp() {
         app = support.Helpers.makeTestApplication();
         Helpers.start(app);
     }
test/models/PasswordResetTest.java
--- test/models/PasswordResetTest.java
+++ test/models/PasswordResetTest.java
@@ -156,14 +156,14 @@
 
         //Then
         assertThat(result).isTrue();
-        assertThat(UserApp.authenticateWithPlainPassword(userId, newPassword).isAnonymous()).isFalse();
+        assertThat(UserApp.authenticateWithPlainPassword(userId, newPassword)).isEqualTo(User.findByLoginId(userId));
     }
 
     @Test
     public void testResetPassword_wrongHash() {
         //Given
         String userId = "doortts";
-        String newPassword = "whffudy";
+        String newPassword = "gomdol";
         String hashString = PasswordReset.generateResetHash(userId);
         PasswordReset.addHashToResetTable(userId, hashString);
 
@@ -173,7 +173,7 @@
 
         //Then
         assertThat(result).isFalse();
-        assertThat(UserApp.authenticateWithPlainPassword(userId, newPassword).isAnonymous()).isTrue();
+        assertThat(UserApp.authenticateWithPlainPassword(userId, newPassword)).isEqualTo(User.anonymous);
     }
 
     private static boolean hashStringExist(String loginId) {
test/playRepository/GitRepositoryTest.java
--- test/playRepository/GitRepositoryTest.java
+++ test/playRepository/GitRepositoryTest.java
@@ -30,18 +30,15 @@
 import org.eclipse.jgit.api.CommitCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.NoFilepatternException;
 import org.eclipse.jgit.lib.*;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevTree;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.treewalk.TreeWalk;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
+import org.junit.*;
 
+import org.junit.rules.TestWatcher;
 import play.test.FakeApplication;
 import play.test.Helpers;
 
@@ -57,6 +54,9 @@
 import static org.fest.assertions.Fail.fail;
 
 public class GitRepositoryTest {
+
+    @Rule
+    public TestWatcher watcher = new ExecutionTimeWatcher();
 
     @Before
     public void before() {
@@ -321,18 +321,6 @@
                 }
             }
         });
-    }
-
-    @Ignore
-    @Test
-    public void getRawFile() throws Exception {
-        // Given
-        String userName = "yobi";
-        String projectName = "testProject";
-        GitRepository repo = new GitRepository(userName, projectName);
-        // When
-        repo.getRawFile("HEAD", "readme");
-        // Then
     }
 
     @Test
test/support/ExecutionTimeWatcher.java (Renamed from test/playRepository/ExecutionTimeWatcher.java)
--- test/playRepository/ExecutionTimeWatcher.java
+++ test/support/ExecutionTimeWatcher.java
@@ -1,4 +1,4 @@
-package playRepository;
+package support;
 
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
test/support/Helpers.java
--- test/support/Helpers.java
+++ test/support/Helpers.java
@@ -70,11 +70,11 @@
         return makeTestApplicationWithServiceGlobal(makeTestConfig());
     }
 
-    private static void insertInitialData() {
+    public static void insertInitialData() {
         YamlUtil.insertDataFromYaml("initial-data.yml", new String[] {"users", "roles", "siteAdmins"});
     }
 
-    private static void insertTestData() {
+    public static void insertTestData() {
         YamlUtil.insertDataFromYaml("test-data.yml", new String[] {
                 "users", "projects", "pullRequests", "milestones",
                 "issues", "issueComments", "postings",
Add a comment
List