Add branch overiew page (#2108)
* Add branch overiew page * fix changed method name on sub menu * remove unused codetokarchuk/v1.17
parent
e86a0bf3fe
commit
3ab580c8d6
@ -0,0 +1,79 @@ |
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package integrations |
||||
|
||||
import ( |
||||
"net/http" |
||||
"net/url" |
||||
"testing" |
||||
|
||||
"github.com/PuerkitoBio/goquery" |
||||
"github.com/Unknwon/i18n" |
||||
"github.com/stretchr/testify/assert" |
||||
) |
||||
|
||||
func TestViewBranches(t *testing.T) { |
||||
prepareTestEnv(t) |
||||
|
||||
req := NewRequest(t, "GET", "/user2/repo1/branches") |
||||
resp := MakeRequest(t, req, http.StatusOK) |
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body) |
||||
_, exists := htmlDoc.doc.Find(".delete-branch-button").Attr("data-url") |
||||
assert.False(t, exists, "The template has changed") |
||||
} |
||||
|
||||
func TestDeleteBranch(t *testing.T) { |
||||
prepareTestEnv(t) |
||||
|
||||
deleteBranch(t) |
||||
} |
||||
|
||||
func TestUndoDeleteBranch(t *testing.T) { |
||||
prepareTestEnv(t) |
||||
|
||||
deleteBranch(t) |
||||
htmlDoc, name := branchAction(t, ".undo-button") |
||||
assert.Contains(t, |
||||
htmlDoc.doc.Find(".ui.positive.message").Text(), |
||||
i18n.Tr("en", "repo.branch.restore_success", name), |
||||
) |
||||
} |
||||
|
||||
func deleteBranch(t *testing.T) { |
||||
htmlDoc, name := branchAction(t, ".delete-branch-button") |
||||
assert.Contains(t, |
||||
htmlDoc.doc.Find(".ui.positive.message").Text(), |
||||
i18n.Tr("en", "repo.branch.deletion_success", name), |
||||
) |
||||
} |
||||
|
||||
func branchAction(t *testing.T, button string) (*HTMLDoc, string) { |
||||
session := loginUser(t, "user2") |
||||
req := NewRequest(t, "GET", "/user2/repo1/branches") |
||||
resp := session.MakeRequest(t, req, http.StatusOK) |
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body) |
||||
link, exists := htmlDoc.doc.Find(button).Attr("data-url") |
||||
assert.True(t, exists, "The template has changed") |
||||
|
||||
htmlDoc = NewHTMLParser(t, resp.Body) |
||||
req = NewRequestWithValues(t, "POST", link, map[string]string{ |
||||
"_csrf": getCsrf(htmlDoc.doc), |
||||
}) |
||||
resp = session.MakeRequest(t, req, http.StatusOK) |
||||
|
||||
url, err := url.Parse(link) |
||||
assert.NoError(t, err) |
||||
req = NewRequest(t, "GET", "/user2/repo1/branches") |
||||
resp = session.MakeRequest(t, req, http.StatusOK) |
||||
|
||||
return NewHTMLParser(t, resp.Body), url.Query()["name"][0] |
||||
} |
||||
|
||||
func getCsrf(doc *goquery.Document) string { |
||||
csrf, _ := doc.Find("meta[name=\"_csrf\"]").Attr("content") |
||||
return csrf |
||||
} |
@ -0,0 +1,89 @@ |
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/assert" |
||||
) |
||||
|
||||
var firstBranch = DeletedBranch{ |
||||
ID: 1, |
||||
Name: "foo", |
||||
Commit: "1213212312313213213132131", |
||||
DeletedByID: int64(1), |
||||
} |
||||
|
||||
var secondBranch = DeletedBranch{ |
||||
ID: 2, |
||||
Name: "bar", |
||||
Commit: "5655464564554545466464655", |
||||
DeletedByID: int64(99), |
||||
} |
||||
|
||||
func TestAddDeletedBranch(t *testing.T) { |
||||
assert.NoError(t, PrepareTestDatabase()) |
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) |
||||
assert.NoError(t, repo.AddDeletedBranch(firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID)) |
||||
assert.Error(t, repo.AddDeletedBranch(firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID)) |
||||
assert.NoError(t, repo.AddDeletedBranch(secondBranch.Name, secondBranch.Commit, secondBranch.DeletedByID)) |
||||
} |
||||
func TestGetDeletedBranches(t *testing.T) { |
||||
assert.NoError(t, PrepareTestDatabase()) |
||||
AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}) |
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) |
||||
|
||||
branches, err := repo.GetDeletedBranches() |
||||
assert.NoError(t, err) |
||||
assert.Len(t, branches, 2) |
||||
} |
||||
|
||||
func TestGetDeletedBranch(t *testing.T) { |
||||
assert.NoError(t, PrepareTestDatabase()) |
||||
assert.NotNil(t, getDeletedBranch(t, firstBranch)) |
||||
} |
||||
|
||||
func TestDeletedBranchLoadUser(t *testing.T) { |
||||
assert.NoError(t, PrepareTestDatabase()) |
||||
branch := getDeletedBranch(t, firstBranch) |
||||
assert.Nil(t, branch.DeletedBy) |
||||
branch.LoadUser() |
||||
assert.NotNil(t, branch.DeletedBy) |
||||
assert.Equal(t, "user1", branch.DeletedBy.Name) |
||||
|
||||
branch = getDeletedBranch(t, secondBranch) |
||||
assert.Nil(t, branch.DeletedBy) |
||||
branch.LoadUser() |
||||
assert.NotNil(t, branch.DeletedBy) |
||||
assert.Equal(t, "Ghost", branch.DeletedBy.Name) |
||||
} |
||||
|
||||
func TestRemoveDeletedBranch(t *testing.T) { |
||||
assert.NoError(t, PrepareTestDatabase()) |
||||
|
||||
branch := DeletedBranch{ID: 1} |
||||
AssertExistsAndLoadBean(t, &branch) |
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) |
||||
|
||||
err := repo.RemoveDeletedBranch(1) |
||||
assert.NoError(t, err) |
||||
AssertNotExistsBean(t, &branch) |
||||
AssertExistsAndLoadBean(t, &DeletedBranch{ID: 2}) |
||||
} |
||||
|
||||
func getDeletedBranch(t *testing.T, branch DeletedBranch) *DeletedBranch { |
||||
AssertExistsAndLoadBean(t, &DeletedBranch{ID: 1}) |
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) |
||||
|
||||
deletedBranch, err := repo.GetDeletedBranchByID(branch.ID) |
||||
assert.NoError(t, err) |
||||
assert.Equal(t, branch.ID, deletedBranch.ID) |
||||
assert.Equal(t, branch.Name, deletedBranch.Name) |
||||
assert.Equal(t, branch.Commit, deletedBranch.Commit) |
||||
assert.Equal(t, branch.DeletedByID, deletedBranch.DeletedByID) |
||||
|
||||
return deletedBranch |
||||
} |
@ -0,0 +1,29 @@ |
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations |
||||
|
||||
import ( |
||||
"fmt" |
||||
|
||||
"github.com/go-xorm/xorm" |
||||
) |
||||
|
||||
func addDeletedBranch(x *xorm.Engine) (err error) { |
||||
// DeletedBranch contains the deleted branch information
|
||||
type DeletedBranch struct { |
||||
ID int64 `xorm:"pk autoincr"` |
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` |
||||
Name string `xorm:"UNIQUE(s) NOT NULL"` |
||||
Commit string `xorm:"UNIQUE(s) NOT NULL"` |
||||
DeletedByID int64 `xorm:"INDEX NOT NULL"` |
||||
DeletedUnix int64 `xorm:"INDEX"` |
||||
} |
||||
|
||||
if err = x.Sync2(new(DeletedBranch)); err != nil { |
||||
return fmt.Errorf("Sync2: %v", err) |
||||
} |
||||
|
||||
return nil |
||||
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,81 @@ |
||||
{{template "base/head" .}} |
||||
<div class="ui repository branches"> |
||||
{{template "repo/header" .}} |
||||
<div class="ui container"> |
||||
{{template "base/alert" .}} |
||||
{{template "repo/sub_menu" .}} |
||||
<h4 class="ui top attached header"> |
||||
{{.i18n.Tr "repo.default_branch"}} |
||||
</h4> |
||||
|
||||
<div class="ui attached table segment"> |
||||
<table class="ui very basic striped fixed table single line"> |
||||
<tbody> |
||||
<tr> |
||||
<td>{{.DefaultBranch}}</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
|
||||
{{if gt (len .Branches) 1}} |
||||
<h4 class="ui top attached header"> |
||||
{{.i18n.Tr "repo.branches"}} |
||||
</h4> |
||||
<div class="ui attached table segment"> |
||||
<table class="ui very basic striped fixed table single line"> |
||||
<thead> |
||||
<tr> |
||||
<th class="nine wide">{{.i18n.Tr "repo.branch.name"}}</th> |
||||
{{if and $.IsWriter (not $.IsMirror)}} |
||||
<th class="one wide right aligned">{{.i18n.Tr "repo.branch.delete_head"}}</th> |
||||
{{end}} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{{range $branch := .Branches}} |
||||
{{if ne .Name $.DefaultBranch}} |
||||
<tr> |
||||
<td> |
||||
{{if .IsDeleted}} |
||||
<s>{{.Name}}</s> |
||||
<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSince .DeletedBranch.Deleted $.i18n.Lang}}</p> |
||||
{{else}} |
||||
{{.Name}} |
||||
<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p> |
||||
</td> |
||||
{{end}} |
||||
{{if and $.IsWriter (not $.IsMirror)}} |
||||
<td class="right aligned"> |
||||
{{if .IsProtected}} |
||||
<i class="octicon octicon-shield"></i> |
||||
{{else if .IsDeleted}} |
||||
<a class="undo-button" href data-url="{{$.Link}}/restore?branch_id={{.DeletedBranch.ID | urlquery}}&name={{.DeletedBranch.Name | urlquery}}"><i class="octicon octicon-reply"></i></a> |
||||
{{else}} |
||||
<a class="delete-branch-button" href data-url="{{$.Link}}/delete?name={{.Name | urlquery}}" data-val="{{.Name}}"><i class="trash icon text red"></i></a> |
||||
{{end}} |
||||
</td> |
||||
{{end}} |
||||
</tr> |
||||
{{end}} |
||||
{{end}} |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
{{end}} |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="ui small basic delete modal"> |
||||
<div class="ui icon header"> |
||||
<i class="trash icon"></i> |
||||
{{.i18n.Tr "repo.branch.delete_html"| Safe}} <span class="branch-name"></span> |
||||
</div> |
||||
<div class="content"> |
||||
<p>{{.i18n.Tr "repo.branch.delete_desc" | Safe}}</p> |
||||
{{.i18n.Tr "repo.branch.delete_notices_1" | Safe}}<br> |
||||
{{.i18n.Tr "repo.branch.delete_notices_html" | Safe}} <span class="branch-name"></span><br> |
||||
</div> |
||||
{{template "base/delete_modal_actions" .}} |
||||
</div> |
||||
{{template "base/footer" .}} |
@ -0,0 +1,14 @@ |
||||
<div class="ui segment sub-menu"> |
||||
<div class="ui two horizontal center link list"> |
||||
{{if and (.Repository.UnitEnabled $.UnitTypeCode) (not .IsBareRepo)}} |
||||
<div class="item{{if .PageIsCommits}} active{{end}}"> |
||||
<a href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}"><i class="octicon octicon-history"></i> <b>{{.CommitsCount}}</b> {{.i18n.Tr "repo.commits"}}</a> |
||||
</div> |
||||
{{end}} |
||||
{{if and (.Repository.UnitEnabled $.UnitTypeCode) (not .IsBareRepo) }} |
||||
<div class="item{{if .PageIsBranches}} active{{end}}"> |
||||
<a href="{{.RepoLink}}/branches/"><i class="octicon octicon-git-branch"></i> <b>{{.BrancheCount}}</b> {{.i18n.Tr "repo.branches"}}</a> |
||||
</div> |
||||
{{end}} |
||||
</div> |
||||
</div> |
Loading…
Reference in new issue