Sangcheol Hwang 2013-01-15
apply markup to user info
@9fcae2ef519e6eafe67c6b4f4f12b27698e550f6
app/models/Project.java
--- app/models/Project.java
+++ app/models/Project.java
@@ -1,5 +1,7 @@
 package models;
 
+import java.io.IOException;
+import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 
@@ -8,160 +10,203 @@
 import javax.persistence.Id;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
+import javax.servlet.ServletException;
 
 import models.enumeration.RoleType;
 import models.task.TaskBoard;
+
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.joda.time.Duration;
+
+import play.Logger;
 import play.data.validation.Constraints;
 import play.db.ebean.Model;
+import playRepository.Commit;
+import playRepository.GitRepository;
 import playRepository.RepositoryService;
+import utils.JodaDateUtil;
 
 import com.avaje.ebean.Page;
 
 /**
- *
+ * 
  * @author "Hwi Ahn"
  */
 
 @Entity
 public class Project extends Model {
-    private static final long serialVersionUID = 1L;
-    public static Finder<Long, Project> find = new Finder<Long, Project>(
-            Long.class, Project.class);
+	private static final long serialVersionUID = 1L;
+	public static Finder<Long, Project> find = new Finder<Long, Project>(
+			Long.class, Project.class);
 
-    @Id
-    public Long id;
+	@Id
+	public Long id;
 
-    @Constraints.Required
-    @Constraints.Pattern("^[a-zA-Z0-9_]*$")
-    public String name;
+	@Constraints.Required
+	@Constraints.Pattern("^[a-zA-Z0-9_]*$")
+	public String name;
 
-    public String overview;
-    public String vcs;
-    public String siteurl;
-    public String logoPath;
-    public String owner;
+	public String overview;
+	public String vcs;
+	public String siteurl;
+	public String logoPath;
+	public String owner;
 
-    public boolean share_option;
-    public boolean isAuthorEditable;
-    
-    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
-    public List<Issue> issues;
-    
-    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
-    public List<ProjectUser> projectUser;
-    
-    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
-    public List<Post> posts;
-    
-    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
-    public List<Milestone> milestones;
-    
-    @OneToOne(mappedBy = "project", cascade = CascadeType.ALL)
-    public TaskBoard taskBoard;
+	public boolean share_option;
+	public boolean isAuthorEditable;
 
-    public static Long create(Project newProject) {
-        newProject.siteurl = "http://localhost:9000/" + newProject.name;
-        newProject.save();
-        ProjectUser.assignRole(User.SITE_MANAGER_ID, newProject.id, RoleType.SITEMANAGER);
-        return newProject.id;
-    }
+	public Date date;
 
-    public static void delete(Long id) {
-        Project.find.byId(id).delete();
-    }
+	@OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
+	public List<Issue> issues;
 
-    public static Page<Project> findByName(String name, int pageSize, int pageNum) {
-        return find.where().ilike("name", "%" + name + "%").findPagingList(pageSize).getPage(pageNum);
-    }
-    
-    public static Project findByNameAndOwner(String userName, String projectName) {
-        return find.where().eq("name", projectName).eq("owner", userName).findUnique();
-    }
-    
-    /**
-     * 해당 프로젝트가 존재하는지 여부를 검사합니다. 해당 파라미터에 대하여 프로젝트가 존재하면 true, 존재하지 않으면 false를 반환합니다.
-     * 
-     * @param userName
-     * @param projectName
-     * @return
-     */
-    public static boolean isProject(String userName, String projectName) {
-        int findRowCount = find.where().eq("name", projectName).eq("owner", userName).findRowCount();
-        return (findRowCount != 0) ? true : false;
-    }
-    
+	@OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
+	public List<ProjectUser> projectUser;
 
-    /**
-     * 프로젝트 이름을 해당 이름(projectName)으로 변경이 가능한지 검사합니다.
-     * 
-     * @param id
-     * @param userName
-     * @param projectName
-     * @return
-     */
-    public static boolean projectNameChangeable(Long id, String userName, String projectName) {
-        int findRowCount = find.where().eq("name", projectName).eq("owner", userName).ne("id", id).findRowCount();
-        return (findRowCount == 0) ? true : false;
-    }
-    
-    /**
-     * 해당 유저가 속해있는 프로젝트들 중에서 해당 유저가 유일한 Manager인 프로젝트가 있는지 검사하고, 
-     * 있다면 그 프로젝트들의 리스트를 반환합니다.
-     * 
-     * @param userId
-     * @return
-     */
-    public static List<Project> isOnlyManager(Long userId) {
-        List<Project> projects = find
-                                    .select("id")
-                                    .select("name")
-                                    .where()
-                                        .eq("projectUser.user.id", userId)
-                                        .eq("projectUser.role.id", RoleType.MANAGER.roleType())
-                                    .findList();
-        Iterator<Project> iterator = projects.iterator();
-        while(iterator.hasNext()){
-            Project project = iterator.next();
-            if(ProjectUser.checkOneMangerPerOneProject(project.id)) {
-                iterator.remove();
-            }
-        }
-        
-        return projects;
-    }
-    
-    /**
-     * 해당 유저가 속해있는 프로젝트들의 리스트를 제공합니다.
-     * 
-     * @param ownerId
-     * @return
-     */
-    public static List<Project> findProjectsByMember(Long userId) {
-        return find.where()
-                .eq("projectUser.user.id", userId).findList();
-    }
+	@OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
+	public List<Post> posts;
 
-    public static Page<Project> projects(int pageNum) {
-        return find.findPagingList(25).getPage(pageNum);
-    }
+	@OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
+	public List<Milestone> milestones;
 
-    public static int countByState(String state) {
-        if (state == "all") {
-            return find.findRowCount();
-        } else if (state == "public") {
-            return find.where().eq("share_option", true).findRowCount();
-        } else if (state == "private") {
-            return find.where().eq("share_option", false).findRowCount();
-        } else {
-            return 0;
-        }
-    }
+	@OneToOne(mappedBy = "project", cascade = CascadeType.ALL)
+	public TaskBoard taskBoard;
 
-    public String readme() {
-        try {
-            return new String(RepositoryService.getRepository(this).getRawFile("README.md"));
-        } catch (Exception e) {
-            return null;
-        }
-    }
+	public static Long create(Project newProject) {
+		newProject.siteurl = "http://localhost:9000/" + newProject.name;
+		newProject.save();
+		ProjectUser.assignRole(User.SITE_MANAGER_ID, newProject.id,
+				RoleType.SITEMANAGER);
+		return newProject.id;
+	}
+
+	public static void delete(Long id) {
+		Project.find.byId(id).delete();
+	}
+
+	public static Page<Project> findByName(String name, int pageSize,
+			int pageNum) {
+		return find.where().ilike("name", "%" + name + "%")
+				.findPagingList(pageSize).getPage(pageNum);
+	}
+
+	public static Project findByNameAndOwner(String userName, String projectName) {
+		return find.where().eq("name", projectName).eq("owner", userName)
+				.findUnique();
+	}
+
+	/**
+	 * 해당 프로젝트가 존재하는지 여부를 검사합니다. 해당 파라미터에 대하여 프로젝트가 존재하면 true, 존재하지 않으면 false를
+	 * 반환합니다.
+	 * 
+	 * @param userName
+	 * @param projectName
+	 * @return
+	 */
+	public static boolean isProject(String userName, String projectName) {
+		int findRowCount = find.where().eq("name", projectName)
+				.eq("owner", userName).findRowCount();
+		return (findRowCount != 0) ? true : false;
+	}
+
+	/**
+	 * 프로젝트 이름을 해당 이름(projectName)으로 변경이 가능한지 검사합니다.
+	 * 
+	 * @param id
+	 * @param userName
+	 * @param projectName
+	 * @return
+	 */
+	public static boolean projectNameChangeable(Long id, String userName,
+			String projectName) {
+		int findRowCount = find.where().eq("name", projectName)
+				.eq("owner", userName).ne("id", id).findRowCount();
+		return (findRowCount == 0) ? true : false;
+	}
+
+	/**
+	 * 해당 유저가 속해있는 프로젝트들 중에서 해당 유저가 유일한 Manager인 프로젝트가 있는지 검사하고, 있다면 그 프로젝트들의
+	 * 리스트를 반환합니다.
+	 * 
+	 * @param userId
+	 * @return
+	 */
+	public static List<Project> isOnlyManager(Long userId) {
+		List<Project> projects = find.select("id").select("name").where()
+				.eq("projectUser.user.id", userId)
+				.eq("projectUser.role.id", RoleType.MANAGER.roleType())
+				.findList();
+		Iterator<Project> iterator = projects.iterator();
+		while (iterator.hasNext()) {
+			Project project = iterator.next();
+			if (ProjectUser.checkOneMangerPerOneProject(project.id)) {
+				iterator.remove();
+			}
+		}
+
+		return projects;
+	}
+
+	/**
+	 * 해당 유저가 속해있는 프로젝트들의 리스트를 제공합니다.
+	 * 
+	 * @param ownerId
+	 * @return
+	 */
+	public static List<Project> findProjectsByMember(Long userId) {
+		return find.where().eq("projectUser.user.id", userId).findList();
+	}
+
+	public static Page<Project> projects(int pageNum) {
+		return find.findPagingList(25).getPage(pageNum);
+	}
+
+	public static int countByState(String state) {
+		if (state == "all") {
+			return find.findRowCount();
+		} else if (state == "public") {
+			return find.where().eq("share_option", true).findRowCount();
+		} else if (state == "private") {
+			return find.where().eq("share_option", false).findRowCount();
+		} else {
+			return 0;
+		}
+	}
+
+	public Date lastUpdateDate() {
+		try {
+			GitRepository gitRepo = new GitRepository(owner, name);
+			List<String> branches = RepositoryService.getRepository(this)
+					.getBranches();
+			if (!branches.isEmpty()) {
+				List<Commit> history = gitRepo.getHistory(0, 2, "HEAD");
+				return history.get(0).getAuthorDate();
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (NoHeadException e) {
+			e.printStackTrace();
+		} catch (GitAPIException e) {
+			e.printStackTrace();
+		} catch (UnsupportedOperationException e) {
+			e.printStackTrace();
+		} catch (ServletException e) {
+			e.printStackTrace();
+		}
+		return this.date;
+	}
+
+	public Duration ago() {
+		return JodaDateUtil.ago(lastUpdateDate());
+	}
+
+	public String readme() {
+		try {
+			return new String(RepositoryService.getRepository(this).getRawFile(
+					"README.md"));
+		} catch (Exception e) {
+			return null;
+		}
+	}
 }
app/models/User.java
--- app/models/User.java
+++ app/models/User.java
@@ -1,5 +1,7 @@
 package models;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -18,10 +20,12 @@
 import models.support.OrderParams;
 import models.support.SearchParams;
 import play.cache.Cached;
+import play.data.format.Formats;
 import play.data.validation.Constraints;
 import play.data.validation.Constraints.Email;
 import play.db.ebean.Model;
 import play.db.ebean.Model.Finder;
+import utils.JodaDateUtil;
 
 import com.avaje.ebean.Page;
 
@@ -52,15 +56,29 @@
     public String avatarUrl;
     
     public boolean rememberMe;
+    
+    @Formats.DateTime(pattern = "yyyy-MM-dd")
+    public Date date;
 
     @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
     public List<ProjectUser> projectUser;
 
+    /**
+     * 완료일을 yyyy-MM-dd 형식의 문자열로 변환시킵니다.
+     *
+     * @return
+     */
+    public String getDateString() {
+        SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
+        return sdf.format(this.date);
+    }
+    
     public List<Project> myProjects(){
         return Project.findProjectsByMember(id);
     }
 
     public static Long create(User user) {
+    	user.date = JodaDateUtil.now();
         user.save();
         return user.id;
     }
app/views/user/info.scala.html
--- app/views/user/info.scala.html
+++ app/views/user/info.scala.html
@@ -1,33 +1,36 @@
 @(user:User)
 
+@import utils.TemplateHelper._
+
 @home("Users Info", utils.MenuType.USER) {
+    @if(user.loginId == session.get("loginId")){
+		<div class="side-menu-wrap">
+		    <ul class="side-menus ico bg-side-menu unstyled">
+		        <li class="side-menu"><a href="@routes.UserApp.editUserInfoForm()"><i class="ico ico-setting on"></i></a></li>
+		    </ul>
+		</div>    
+    }
 
 <div class="page-wrap container">
     <div class="page">
-        <h1 class="page-title"><span class="gray">nforge4/</span>SW.CHAE</h1>
+        <div>
+            <div><h1 class="page-title">@user.loginId</h1></div>
+        </div>
+        
         <section class="user-box">
             <div class="user-info-box">
                 <div class="whoami-wrap">
-                    <p class="uname">SW.CHAE</p>
-                    <p class="name">(doortts)</p>
-                    <img src="/images/default-avatar-128.png" width="127" height="127" class="img-rounded">
+                                  <p class="uname">@user.name</p>
+                    <p class="name">(@user.loginId)</p>
+                    <img src="@user.avatarUrl" width="127" height="127" class="img-rounded">
                 </div>
                 <div class="user-location info-box">
-                    <p class="u-location"><i class="ico ico-location"></i>Seoul, Korea, South</p>
-                </div>
-                <hr/>
-                <div class="user-status info-box">
-                    <p><span class="labels">My projects</span><span class="num">6350</span></p>
-                    <p><span class="labels">Followers</span><span class="num">6350</span></p>
-                    <p><span class="labels">Following</span><span class="num">521385</span></p>
-                    <p><span class="labels">Starred</span><span class="num">323</span></p>
+                    <p class="u-location"><i class="ico ico-location"></i>@user.email</p>
                 </div>
                 <hr/>
                 <div class="user-other-info info-box">
-                    <p><strong>FOCUS</strong></p>
-                    <p class="focuses">C#, JAVA, SQL, JAVASCRIPT</p>
                     <p class="since"><strong>MEMBER SINCE</strong></p>
-                    <p><span class="since">November 22, 2012</span></p>
+                    <p><span class="since">@user.getDateString</span></p>
                     <p class="social-btns">
                         <a href="http://twitter.com/nforge"><i class="ico btn-tw"></i></a>
                         <a href="http://facebook.com/nforge"><i class="ico btn-fb"></i></a>
@@ -36,228 +39,41 @@
                 </div>
                 <hr/>
                 <div class="btn-wrap">
-                    <a href="/new-project"><i class="ico btn-new-project"></i></a>
+                    <a href="/projectform"><i class="ico btn-new-project"></i></a>
                 </div>
             </div>
             <div class="user-stream-box">
                 <ul class="nav nav-tabs user-stream-tab">
                     <li class="active"><a href="user-setting.html">Repositories</a></li>
-                    <li><a href="user-activities.html">Activities</a></li>
+                    <!-- li><a href="user-activities.html">Activities</a></li-->
                 </ul>
-                <div class="user-stream-wrap">
-                    <div class="header-wrap">
-                        <div class="search-wrap user-setting">
-                            <div class="inner">
-                                <form action="/activity-search" method="get">
-                                    <input name="query" class="text" type="text" placeholder="검색"><button type="submit" class="btn-transparent search-btn">SEARCH</button>
-                                </form>
-                            </div>
-                        </div>
-                    </div>
+                <!-- div class="user-stream-wrap">
                     <div class="filter-wrap user-setting">
                         <div class="filters">
                             <a href="/html/user-setting.html" class="filter"><i class="ico btn-gray-arrow"></i>전체</a>
                             <a href="/html/user-activities.html?order=staus" class="filter active"><i class="ico btn-gray-arrow down"></i>상태순</a>
                         </div>
                     </div>
-                </div>
+                </div-->
                 <ul class="user-streams">
+                @for(project <- user.myProjects()){                
                     <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
+                        <h3 class="project-name"><a href="@routes.ProjectApp.project(project.owner, project.name)">@project.owner/@project.name</a></h3>
                         <div class="stream-desc-wrap">
                             <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
+                                <!-- p class="nm">최근 활동 관련 영역입니다.</p-->
+                                <p class="date">Last updated @agoString(project.ago)</p>
                             </div>
-                            <div class="project-status">
+                            <!-- div class="project-status">
                                 <i class="ico ico-like"></i><span class="num">1</span>
                                 <i class="ico ico-activity high"></i>
-                            </div>
+                            </div-->
                         </div>
                     </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.  활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
-                    <li class="user-stream">
-                        <h3 class="project-name">nforge4</h3>
-                        <div class="stream-desc-wrap">
-                            <div class="stream-desc">
-                                <p class="nm">최근 활동 관련 영역입니다.</p>
-                                <p class="date">Last updated 2 months ago</p>
-                            </div>
-                            <div class="project-status">
-                                <i class="ico ico-like"></i><span class="num">1</span>
-                                <i class="ico ico-activity high"></i>
-                            </div>
-                        </div>
-                    </li>
+                }
                 </ul>
             </div>
         </section>
-    </div>
-</div>
-
-
-
-<div class="page">
-
-	<h1 class="page-title">
-		@user.loginId
-	</h1>
-	@if(user.loginId == session.get("loginId")){
-		  <a href="@routes.UserApp.editUserInfoForm()" class="btn">수정</a>
-	}
-	
-	<div class="bubble-wrap dark-gray project-home">
-		<div class="inner logo">
-            <div class="logo-wrap">
-                <img src="@user.avatarUrl" />
-            </div>
-        </div>
-        <div class="inner project-info">
-            <header>
-                <h3>프로파일 정보</h3>
-            </header>
-            <ul class="infos">
-                <li class="info">
-                    <strong>로그인 아이디 :</strong> @user.loginId
-                </li>
-                <li class="info">
-                    <strong>이름 :</strong> @user.name
-                </li>
-                <li class="info">
-                    <strong>이메일 :</strong> @user.email
-                </li>
-            </ul>
-        </div>
-        <div class="inner member-info">
-            <header>
-                <h3>프로젝트 정보</h3>
-            </header>
-            <div class="member-wrap">
-                <ul class="project-members">
-                    @for(project <- user.myProjects()){
-                    <li class="member">
-                        <a href="@routes.ProjectApp.project(project.owner, project.name)"><strong>@project.name</strong></a>
-                    </li>
-                    }
-                </ul>
-            </div>
-        </div>
     </div>
 </div>
 }
conf/initial-data.yml
--- conf/initial-data.yml
+++ conf/initial-data.yml
@@ -7,6 +7,7 @@
         passwordSalt:   '[B@1032a4'
         email:          admin@nhn.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-11-01 08:00:00
     - !!models.User
         name:           Hobi
         loginId:        hobi
@@ -14,6 +15,7 @@
         passwordSalt:   '[B@1032a4'        
         email:          hobi@nhn.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-12-01 08:00:00
     - !!models.User
         name:           scott
         loginId:        k16wire
@@ -21,6 +23,7 @@
         passwordSalt:   '[B@1032a4'        
         email:          k16wire@naver.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-01-01 08:00:00
     - !!models.User
         name:           suwon
         loginId:        doortts
@@ -28,6 +31,7 @@
         passwordSalt:   '[B@1032a4'        
         email:          doortts@gmail.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-07-01 08:00:00
     - !!models.User
         name:           eungjun
         loginId:        nori
@@ -35,12 +39,14 @@
         passwordSalt:   '[B@1032a4'        
         email:          ejlee@nhn.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-05-01 08:00:00
     - !!models.User
         name:           anonymous
         loginId:        anonymous
         password:       
         email:          anonymous@nhn.com
         avatarUrl:      /assets/images/default-avatar-128.png
+        date:           2012-02-01 08:00:00
         
 # Projects
 projects:
@@ -52,6 +58,7 @@
         siteurl:       http://localhost:9000/nForge4java
         owner:          hobi
         isAuthorEditable: true
+        date:           2012-02-01 08:00:00
     - !!models.Project
         name:           Jindo
         overview:       Jindo는 NHN에서 제작한 Javascript Library 이다.
@@ -60,6 +67,7 @@
         siteurl:       http://localhost:9000/Jindo
         owner:          k16wire
         isAuthorEditable: false
+        date:           2012-01-01 08:00:00        
     - !!models.Project
         name:           CUBRID
         overview:       CUBRID는 엔터프라이즈급 오픈 소스 DBMS로서, 인터넷 서비스에 최적화된 DBMS를 지향하고 있습니다.
@@ -68,6 +76,7 @@
         siteurl:       http://localhost:9000/CUBRID
         owner:          doortts
         isAuthorEditable: true
+        date:           2012-08-01 08:00:00        
     - !!models.Project
         name:           HelloSocialApp
         overview:       네이버 앱팩토리 플랫폼에서 제공하는 오픈소셜 API를 직접 실행해 볼 수 있는 애플리케이션입니다.
@@ -76,6 +85,7 @@
         siteurl:       http://localhost:9000/HelloSocialApp
         owner:          hobi
         isAuthorEditable: true
+        date:           2012-12-01 08:00:00        
 
 # Board
 posts:
@@ -107,7 +117,7 @@
         body:           내용 불필요한~
         state:          OPEN
         milestoneId:    1
-        date: 2012-11-01 08:00:00
+        date:           2012-11-01 08:00:00
         project:        !!models.Project
                             id: 1
     - !!models.Issue
test/models/ProjectTest.java
--- test/models/ProjectTest.java
+++ test/models/ProjectTest.java
@@ -1,13 +1,22 @@
 package models;
 
+import static org.fest.assertions.Assertions.assertThat;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.List;
+
+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.Repository;
+import org.eclipse.jgit.lib.RepositoryBuilder;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import controllers.UserApp;
-
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
+import playRepository.Commit;
+import playRepository.GitRepository;
 
 /**
  * @author "Hwi Ahn"
@@ -136,4 +145,35 @@
         assertThat(result1).isEqualTo(false);
         assertThat(result2).isEqualTo(true);
     }
+    
+    @Test
+    public void lastUpdate() throws Exception {
+        // given
+        String userName = "hobi";
+        String projectName = "testProject";
+        String wcPath = GitRepository.getRepoPrefix() + userName + "/" + projectName;
+
+        String repoPath = wcPath + "/.git";
+        File repoDir = new File(repoPath);
+        Repository repo = new RepositoryBuilder().setGitDir(repoDir).build();
+        repo.create(false);
+
+        Git git = new Git(repo);
+        String testFilePath = wcPath + "/readme.txt";
+        BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath));
+
+        out.write("hello 1");
+        out.flush();
+        git.add().addFilepattern("readme.txt").call();
+        git.commit().setMessage("commit 1").call();
+
+        GitRepository gitRepo = new GitRepository(userName, projectName + "/");
+        
+//    	Project project = Project.findByNameAndOwner(userName, projectName);
+    	// When
+    	List<Commit> history = gitRepo.getHistory(0, 2, "HEAD");
+    	Commit commit = history.get(0);
+    	// Then
+    	assertThat(commit.getAuthorDate()).isNotNull();
+    }
 }
Add a comment
List