Files
forge/tests/integration/api_repo_branch_test.go
zeekayandHanzo Dev aa87442fdd Record upstream authorship centrally in NOTICE instead of in every file header
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the
Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in
NOTICE, alongside LICENSE. The header lint accepts any copyright line above the
SPDX line, so it no longer demands an upstream one.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:50:35 -07:00

148 lines
6.2 KiB
Go

// Copyright 2026 Hanzo AI, Inc. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"testing"
auth_model "github.com/hanzoai/git/models/auth"
repo_model "github.com/hanzoai/git/models/repo"
"github.com/hanzoai/git/models/unittest"
user_model "github.com/hanzoai/git/models/user"
"github.com/hanzoai/git/modules/json"
"github.com/hanzoai/git/modules/setting"
api "github.com/hanzoai/git/modules/structs"
"github.com/hanzoai/git/tests"
"github.com/stretchr/testify/assert"
)
func TestAPIRepoBranchesPlain(t *testing.T) {
onGitRun(t, func(*testing.T, *url.URL) {
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user1.LowerName)
// public-only token cannot see a private repo
publicOnlyToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopePublicOnly, auth_model.AccessTokenScopeWriteRepository)
link, _ := url.Parse(fmt.Sprintf("/v1/repos/org3/%s/branches", repo3.Name)) // a plain repo
MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(publicOnlyToken), http.StatusNotFound)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
resp := MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK)
bs, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
var branches []*api.Branch
assert.NoError(t, json.Unmarshal(bs, &branches))
assert.Len(t, branches, 2)
assert.Equal(t, "test_branch", branches[0].Name)
assert.Equal(t, "master", branches[1].Name)
link2, _ := url.Parse(fmt.Sprintf("/v1/repos/org3/%s/branches/test_branch", repo3.Name))
MakeRequest(t, NewRequest(t, "GET", link2.String()).AddTokenAuth(publicOnlyToken), http.StatusNotFound)
resp = MakeRequest(t, NewRequest(t, "GET", link2.String()).AddTokenAuth(token), http.StatusOK)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
var branch api.Branch
assert.NoError(t, json.Unmarshal(bs, &branch))
assert.Equal(t, "test_branch", branch.Name)
MakeRequest(t, NewRequest(t, "POST", link.String()).AddTokenAuth(publicOnlyToken), http.StatusNotFound)
req := NewRequest(t, "POST", link.String()).AddTokenAuth(token)
req.Header.Add("Content-Type", "application/json")
req.Body = io.NopCloser(strings.NewReader(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`))
resp = MakeRequest(t, req, http.StatusCreated)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
var branch2 api.Branch
assert.NoError(t, json.Unmarshal(bs, &branch2))
assert.Equal(t, "test_branch2", branch2.Name)
assert.Equal(t, branch.Commit.ID, branch2.Commit.ID)
resp = MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
branches = []*api.Branch{}
assert.NoError(t, json.Unmarshal(bs, &branches))
assert.Len(t, branches, 3)
assert.Equal(t, "test_branch", branches[0].Name)
assert.Equal(t, "test_branch2", branches[1].Name)
assert.Equal(t, "master", branches[2].Name)
link3, _ := url.Parse(fmt.Sprintf("/v1/repos/org3/%s/branches/test_branch2", repo3.Name))
MakeRequest(t, NewRequest(t, "DELETE", link3.String()), http.StatusNotFound)
MakeRequest(t, NewRequest(t, "DELETE", link3.String()).AddTokenAuth(publicOnlyToken), http.StatusNotFound)
MakeRequest(t, NewRequest(t, "DELETE", link3.String()).AddTokenAuth(token), http.StatusNoContent)
assert.NoError(t, err)
})
}
func TestAPIRepoBranchesMirror(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo5 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 5})
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user1.LowerName)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
link, _ := url.Parse(fmt.Sprintf("/v1/repos/org3/%s/branches", repo5.Name)) // a mirror repo
resp := MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK)
bs, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
var branches []*api.Branch
assert.NoError(t, json.Unmarshal(bs, &branches))
assert.Len(t, branches, 2)
assert.Equal(t, "test_branch", branches[0].Name)
assert.Equal(t, "master", branches[1].Name)
link2, _ := url.Parse(fmt.Sprintf("/v1/repos/org3/%s/branches/test_branch", repo5.Name))
resp = MakeRequest(t, NewRequest(t, "GET", link2.String()).AddTokenAuth(token), http.StatusOK)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
var branch api.Branch
assert.NoError(t, json.Unmarshal(bs, &branch))
assert.Equal(t, "test_branch", branch.Name)
req := NewRequest(t, "POST", link.String()).AddTokenAuth(token)
req.Header.Add("Content-Type", "application/json")
req.Body = io.NopCloser(strings.NewReader(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`))
resp = MakeRequest(t, req, http.StatusForbidden)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
assert.JSONEq(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"swagger\"}", string(bs))
resp = MakeRequest(t, NewRequest(t, "DELETE", link2.String()).AddTokenAuth(token), http.StatusForbidden)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
assert.JSONEq(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"swagger\"}", string(bs))
}
func TestAPIRepoBranchesSearch(t *testing.T) {
defer tests.PrepareTestEnv(t)()
token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteRepository)
// "test" matches "test_branch" but not "master"
resp := MakeRequest(t, NewRequestf(t, "GET", "/v1/repos/org3/repo3/branches?q=test").AddTokenAuth(token), http.StatusOK)
branches := DecodeJSON(t, resp, []api.Branch{})
assert.Len(t, branches, 1)
assert.Equal(t, "test_branch", branches[0].Name)
// no match returns empty list
resp = MakeRequest(t, NewRequestf(t, "GET", "/v1/repos/org3/repo3/branches?q=doesnotexist").AddTokenAuth(token), http.StatusOK)
branches = DecodeJSON(t, resp, []api.Branch{})
assert.Empty(t, branches)
}