Support org labels when adding labels by label names (#32988)
Fix #32891
(cherry picked from commit 44b4fb21a4e99f327303f66cc7e48f7ca7ba09e1)
(cherry picked from commit 92ac337263)
	
	
This commit is contained in:
		
					parent
					
						
							
								2bcbfbc5d4
							
						
					
				
			
			
				commit
				
					
						2ac9b16297
					
				
			
		
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue