mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-01-07 21:04:38 +01:00
Support org labels when adding labels by label names (#32988)
Fix #32891 (cherry picked from commit 44b4fb21a4e99f327303f66cc7e48f7ca7ba09e1)
This commit is contained in:
parent
2ffa9a5e6e
commit
92ac337263
4 changed files with 50 additions and 10 deletions
|
@ -96,3 +96,14 @@
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
num_closed_issues: 0
|
num_closed_issues: 0
|
||||||
archived_unix: 0
|
archived_unix: 0
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 10
|
||||||
|
repo_id: 3
|
||||||
|
org_id: 0
|
||||||
|
name: repo3label1
|
||||||
|
color: '#112233'
|
||||||
|
exclusive: false
|
||||||
|
num_issues: 0
|
||||||
|
num_closed_issues: 0
|
||||||
|
archived_unix: 0
|
||||||
|
|
|
@ -353,6 +353,17 @@ func GetLabelIDsInRepoByNames(ctx context.Context, repoID int64, labelNames []st
|
||||||
Find(&labelIDs)
|
Find(&labelIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLabelIDsInOrgByNames returns a list of labelIDs by names in a given org.
|
||||||
|
func GetLabelIDsInOrgByNames(ctx context.Context, orgID int64, labelNames []string) ([]int64, error) {
|
||||||
|
labelIDs := make([]int64, 0, len(labelNames))
|
||||||
|
return labelIDs, db.GetEngine(ctx).Table("label").
|
||||||
|
Where("org_id = ?", orgID).
|
||||||
|
In("name", labelNames).
|
||||||
|
Asc("name").
|
||||||
|
Cols("id").
|
||||||
|
Find(&labelIDs)
|
||||||
|
}
|
||||||
|
|
||||||
// BuildLabelNamesIssueIDsCondition returns a builder where get issue ids match label names
|
// BuildLabelNamesIssueIDsCondition returns a builder where get issue ids match label names
|
||||||
func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
|
func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
|
||||||
return builder.Select("issue_label.issue_id").
|
return builder.Select("issue_label.issue_id").
|
||||||
|
|
|
@ -350,6 +350,9 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption)
|
||||||
labelIDs = append(labelIDs, int64(rv.Float()))
|
labelIDs = append(labelIDs, int64(rv.Float()))
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
labelNames = append(labelNames, rv.String())
|
labelNames = append(labelNames, rv.String())
|
||||||
|
default:
|
||||||
|
ctx.Error(http.StatusBadRequest, "InvalidLabel", "a label must be an integer or a string")
|
||||||
|
return nil, nil, fmt.Errorf("invalid label")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(labelIDs) > 0 && len(labelNames) > 0 {
|
if len(labelIDs) > 0 && len(labelNames) > 0 {
|
||||||
|
@ -357,11 +360,20 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption)
|
||||||
return nil, nil, fmt.Errorf("invalid labels")
|
return nil, nil, fmt.Errorf("invalid labels")
|
||||||
}
|
}
|
||||||
if len(labelNames) > 0 {
|
if len(labelNames) > 0 {
|
||||||
labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames)
|
repoLabelIDs, err := issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err)
|
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
labelIDs = append(labelIDs, repoLabelIDs...)
|
||||||
|
if ctx.Repo.Owner.IsOrganization() {
|
||||||
|
orgLabelIDs, err := issues_model.GetLabelIDsInOrgByNames(ctx, ctx.Repo.Owner.ID, labelNames)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInOrgByNames", err)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
labelIDs = append(labelIDs, orgLabelIDs...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs, "id", "repo_id", "org_id", "name", "exclusive")
|
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs, "id", "repo_id", "org_id", "name", "exclusive")
|
||||||
|
|
|
@ -120,27 +120,33 @@ func TestAPIAddIssueLabels(t *testing.T) {
|
||||||
func TestAPIAddIssueLabelsWithLabelNames(t *testing.T) {
|
func TestAPIAddIssueLabelsWithLabelNames(t *testing.T) {
|
||||||
require.NoError(t, unittest.LoadFixtures())
|
require.NoError(t, unittest.LoadFixtures())
|
||||||
|
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
|
||||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID})
|
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 6, RepoID: repo.ID})
|
||||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||||
|
repoLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 10, RepoID: repo.ID})
|
||||||
|
orgLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4, OrgID: owner.ID})
|
||||||
|
|
||||||
session := loginUser(t, owner.Name)
|
user1Session := loginUser(t, "user1")
|
||||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue)
|
token := getTokenForLoggedInUser(t, user1Session, auth_model.AccessTokenScopeWriteIssue)
|
||||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels",
|
|
||||||
repo.OwnerName, repo.Name, issue.Index)
|
// add the org label and the repo label to the issue
|
||||||
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", owner.Name, repo.Name, issue.Index)
|
||||||
req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{
|
||||||
Labels: []any{"label1", "label2"},
|
Labels: []any{repoLabel.Name, orgLabel.Name},
|
||||||
}).AddTokenAuth(token)
|
}).AddTokenAuth(token)
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
var apiLabels []*api.Label
|
var apiLabels []*api.Label
|
||||||
DecodeJSON(t, resp, &apiLabels)
|
DecodeJSON(t, resp, &apiLabels)
|
||||||
assert.Len(t, apiLabels, unittest.GetCount(t, &issues_model.IssueLabel{IssueID: issue.ID}))
|
assert.Len(t, apiLabels, unittest.GetCount(t, &issues_model.IssueLabel{IssueID: issue.ID}))
|
||||||
|
|
||||||
var apiLabelNames []string
|
var apiLabelNames []string
|
||||||
for _, label := range apiLabels {
|
for _, label := range apiLabels {
|
||||||
apiLabelNames = append(apiLabelNames, label.Name)
|
apiLabelNames = append(apiLabelNames, label.Name)
|
||||||
}
|
}
|
||||||
assert.ElementsMatch(t, apiLabelNames, []string{"label1", "label2"})
|
assert.ElementsMatch(t, apiLabelNames, []string{repoLabel.Name, orgLabel.Name})
|
||||||
|
|
||||||
|
// delete labels
|
||||||
|
req = NewRequest(t, "DELETE", urlStr).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIAddIssueLabelsAutoDate(t *testing.T) {
|
func TestAPIAddIssueLabelsAutoDate(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue