mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
Consolidate all Go tests. Coverage is identical to before. Go tests are around 5% faster while being 7% smaller. No non-test code is touched.
126 lines
4.5 KiB
Go
126 lines
4.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package project
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dev/models/db"
|
|
issues_model "gitea.dev/models/issues"
|
|
"gitea.dev/models/organization"
|
|
"gitea.dev/models/perm"
|
|
project_model "gitea.dev/models/project"
|
|
repo_model "gitea.dev/models/repo"
|
|
"gitea.dev/models/unit"
|
|
"gitea.dev/models/unittest"
|
|
user_model "gitea.dev/models/user"
|
|
"gitea.dev/services/contexttest"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
unittest.MainTest(m)
|
|
}
|
|
|
|
// TestFindColumn covers the scoping rule every board handler depends on: a request only
|
|
// resolves projects owned by the scope its route assigned, so an ID belonging to anyone
|
|
// else reads as not found rather than leaking across owners.
|
|
func TestFindColumn(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
for _, tc := range []struct {
|
|
name string
|
|
projectID string
|
|
columnID string
|
|
doerID int64
|
|
repoScoped bool
|
|
resolves bool
|
|
}{
|
|
{"repository project", "1", "2", 2, true, true},
|
|
{"owner project", "4", "4", 2, false, true},
|
|
{"repository board cannot reach an owner project", "4", "1", 2, true, false},
|
|
{"owner board cannot reach another owner's project", "4", "4", 1, false, false},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
ctx, _ := contexttest.MockContext(t, "user2/-/projects")
|
|
contexttest.LoadUser(t, ctx, tc.doerID)
|
|
if tc.repoScoped {
|
|
contexttest.LoadRepo(t, ctx, 1)
|
|
} else {
|
|
ctx.ContextUser = ctx.Doer
|
|
}
|
|
ctx.SetPathParam("id", tc.projectID)
|
|
ctx.SetPathParam("columnID", tc.columnID)
|
|
|
|
project, column := findColumn(ctx)
|
|
assert.Equal(t, tc.resolves, project != nil)
|
|
assert.Equal(t, tc.resolves, column != nil)
|
|
if tc.resolves {
|
|
assert.False(t, ctx.Written())
|
|
} else {
|
|
// a foreign ID must read as not found, never as a 500
|
|
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMoveIssuesNeedsIssueRead(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
doerID int64
|
|
repoBoard bool
|
|
archived bool
|
|
status int
|
|
}{
|
|
{"OwnerBoardReader", 2, false, false, http.StatusOK},
|
|
{"OwnerBoardWithoutIssueAccess", 15, false, false, http.StatusNotFound},
|
|
{"OwnerBoardArchivedRepo", 2, false, true, http.StatusLocked},
|
|
{"RepoBoardProjectsWriterWithoutIssueRead", 4, true, false, http.StatusNotFound},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
if tc.repoBoard {
|
|
_, err := db.Exec(t.Context(), "UPDATE team SET authorize = ? WHERE id = ?", perm.AccessModeNone, 2)
|
|
require.NoError(t, err)
|
|
_, err = db.DeleteByBean(t.Context(), &organization.TeamUnit{TeamID: 2, Type: unit.TypeIssues})
|
|
require.NoError(t, err)
|
|
}
|
|
if tc.archived {
|
|
require.NoError(t, repo_model.UpdateRepositoryColsNoAutoTime(t.Context(), &repo_model.Repository{ID: 3, IsArchived: true}, "is_archived"))
|
|
}
|
|
ctx, _ := contexttest.MockContext(t, "POST /org3/-/projects")
|
|
contexttest.LoadUser(t, ctx, tc.doerID)
|
|
project := unittest.AssertExistsAndLoadBean(t, &project_model.Project{ID: 2})
|
|
if tc.repoBoard {
|
|
contexttest.LoadRepo(t, ctx, 3)
|
|
} else {
|
|
ctx.ContextUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
|
|
project = &project_model.Project{Title: "board", OwnerID: 3, CreatorID: 2, Type: project_model.TypeOrganization}
|
|
require.NoError(t, project_model.NewProject(ctx, project))
|
|
require.NoError(t, project_model.NewColumn(ctx, &project_model.Column{Title: "Backlog", ProjectID: project.ID, Default: true}))
|
|
}
|
|
column := &project_model.Column{Title: "Done", ProjectID: project.ID}
|
|
require.NoError(t, project_model.NewColumn(ctx, column))
|
|
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 6})
|
|
_, _, err := issues_model.IssueAssignOrRemoveProject(ctx, issue, unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}), []int64{project.ID})
|
|
require.NoError(t, err)
|
|
ctx.SetPathParam("id", strconv.FormatInt(project.ID, 10))
|
|
ctx.SetPathParam("columnID", strconv.FormatInt(column.ID, 10))
|
|
ctx.Req.Body = io.NopCloser(strings.NewReader(fmt.Sprintf(`{"issues":[{"issueID":%d,"sorting":0}]}`, issue.ID)))
|
|
|
|
MoveIssues(ctx)
|
|
assert.Equal(t, tc.status, ctx.Resp.WrittenStatus())
|
|
card := unittest.AssertExistsAndLoadBean(t, &project_model.ProjectIssue{IssueID: issue.ID, ProjectID: project.ID})
|
|
assert.Equal(t, tc.status == http.StatusOK, card.ProjectColumnID == column.ID)
|
|
})
|
|
}
|
|
}
|