mirror of https://github.com/go-gitea/gitea.git
Add branch overiew page (#2108)
* Add branch overiew page * fix changed method name on sub menu * remove unused codepull/2774/head^2
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