mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 06:21:11 +00:00 
			
		
		
		
	More about codespell: https://github.com/codespell-project/codespell . I personally introduced it to dozens if not hundreds of projects already and so far only positive feedback. ``` ❯ grep lint-spell Makefile @echo " - lint-spell lint spelling" @echo " - lint-spell-fix lint spelling and fix issues" lint: lint-frontend lint-backend lint-spell lint-fix: lint-frontend-fix lint-backend-fix lint-spell-fix .PHONY: lint-spell lint-spell: lint-codespell .PHONY: lint-spell-fix lint-spell-fix: lint-codespell-fix ❯ git grep lint- -- .forgejo/ .forgejo/workflows/testing.yml: - run: make --always-make -j$(nproc) lint-backend checks-backend # ensure the "go-licenses" make target runs .forgejo/workflows/testing.yml: - run: make lint-frontend ``` so how would you like me to invoke `lint-codespell` on CI? (without that would be IMHO very suboptimal and let typos sneak in) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3270 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: Yaroslav Halchenko <debian@onerussian.com> Co-committed-by: Yaroslav Halchenko <debian@onerussian.com>
		
			
				
	
	
		
			215 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2024 The Forgejo Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package integration
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"net/url"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"code.gitea.io/gitea/models/db"
 | |
| 	git_model "code.gitea.io/gitea/models/git"
 | |
| 	issues_model "code.gitea.io/gitea/models/issues"
 | |
| 	unit_model "code.gitea.io/gitea/models/unit"
 | |
| 	"code.gitea.io/gitea/models/unittest"
 | |
| 	user_model "code.gitea.io/gitea/models/user"
 | |
| 	"code.gitea.io/gitea/modules/git"
 | |
| 	"code.gitea.io/gitea/modules/translation"
 | |
| 	gitea_context "code.gitea.io/gitea/services/context"
 | |
| 	issue_service "code.gitea.io/gitea/services/issue"
 | |
| 	pull_service "code.gitea.io/gitea/services/pull"
 | |
| 	repo_service "code.gitea.io/gitea/services/repository"
 | |
| 	files_service "code.gitea.io/gitea/services/repository/files"
 | |
| 	"code.gitea.io/gitea/tests"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| )
 | |
| 
 | |
| func TestPullrequestReopen(t *testing.T) {
 | |
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) {
 | |
| 		user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 | |
| 		org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
 | |
| 
 | |
| 		// Create an base repository.
 | |
| 		baseRepo, _, f := CreateDeclarativeRepo(t, user2, "reopen-base",
 | |
| 			[]unit_model.Type{unit_model.TypePullRequests}, nil, nil,
 | |
| 		)
 | |
| 		defer f()
 | |
| 
 | |
| 		// Create a new branch on the base branch, so it can be deleted later.
 | |
| 		_, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{
 | |
| 			Files: []*files_service.ChangeRepoFile{
 | |
| 				{
 | |
| 					Operation:     "update",
 | |
| 					TreePath:      "README.md",
 | |
| 					ContentReader: strings.NewReader("New README.md"),
 | |
| 				},
 | |
| 			},
 | |
| 			Message:   "Modify README for base",
 | |
| 			OldBranch: "main",
 | |
| 			NewBranch: "base-branch",
 | |
| 			Author: &files_service.IdentityOptions{
 | |
| 				Name:  user2.Name,
 | |
| 				Email: user2.Email,
 | |
| 			},
 | |
| 			Committer: &files_service.IdentityOptions{
 | |
| 				Name:  user2.Name,
 | |
| 				Email: user2.Email,
 | |
| 			},
 | |
| 			Dates: &files_service.CommitDateOptions{
 | |
| 				Author:    time.Now(),
 | |
| 				Committer: time.Now(),
 | |
| 			},
 | |
| 		})
 | |
| 		assert.NoError(t, err)
 | |
| 
 | |
| 		// Create an head repository.
 | |
| 		headRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, org26, repo_service.ForkRepoOptions{
 | |
| 			BaseRepo: baseRepo,
 | |
| 			Name:     "reopen-head",
 | |
| 		})
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.NotEmpty(t, headRepo)
 | |
| 
 | |
| 		// Add a change to the head repository, so a pull request can be opened.
 | |
| 		_, err = files_service.ChangeRepoFiles(git.DefaultContext, headRepo, user2, &files_service.ChangeRepoFilesOptions{
 | |
| 			Files: []*files_service.ChangeRepoFile{
 | |
| 				{
 | |
| 					Operation:     "update",
 | |
| 					TreePath:      "README.md",
 | |
| 					ContentReader: strings.NewReader("Updated README.md"),
 | |
| 				},
 | |
| 			},
 | |
| 			Message:   "Modify README for head",
 | |
| 			OldBranch: "main",
 | |
| 			NewBranch: "head-branch",
 | |
| 			Author: &files_service.IdentityOptions{
 | |
| 				Name:  user2.Name,
 | |
| 				Email: user2.Email,
 | |
| 			},
 | |
| 			Committer: &files_service.IdentityOptions{
 | |
| 				Name:  user2.Name,
 | |
| 				Email: user2.Email,
 | |
| 			},
 | |
| 			Dates: &files_service.CommitDateOptions{
 | |
| 				Author:    time.Now(),
 | |
| 				Committer: time.Now(),
 | |
| 			},
 | |
| 		})
 | |
| 		assert.NoError(t, err)
 | |
| 
 | |
| 		// Create the pull request.
 | |
| 		pullIssue := &issues_model.Issue{
 | |
| 			RepoID:   baseRepo.ID,
 | |
| 			Title:    "Testing reopen functionality",
 | |
| 			PosterID: user2.ID,
 | |
| 			Poster:   user2,
 | |
| 			IsPull:   true,
 | |
| 		}
 | |
| 		pullRequest := &issues_model.PullRequest{
 | |
| 			HeadRepoID: headRepo.ID,
 | |
| 			BaseRepoID: baseRepo.ID,
 | |
| 			HeadBranch: "head-branch",
 | |
| 			BaseBranch: "base-branch",
 | |
| 			HeadRepo:   headRepo,
 | |
| 			BaseRepo:   baseRepo,
 | |
| 			Type:       issues_model.PullRequestGitea,
 | |
| 		}
 | |
| 		err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil)
 | |
| 		assert.NoError(t, err)
 | |
| 
 | |
| 		issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Testing reopen functionality"})
 | |
| 
 | |
| 		// Close the PR.
 | |
| 		err = issue_service.ChangeStatus(db.DefaultContext, issue, user2, "", true)
 | |
| 		assert.NoError(t, err)
 | |
| 
 | |
| 		session := loginUser(t, "user2")
 | |
| 
 | |
| 		reopenPR := func(t *testing.T, expectedStatus int) *httptest.ResponseRecorder {
 | |
| 			t.Helper()
 | |
| 
 | |
| 			link := fmt.Sprintf("%s/pulls/%d/comments", baseRepo.FullName(), issue.Index)
 | |
| 			req := NewRequestWithValues(t, "POST", link, map[string]string{
 | |
| 				"_csrf":  GetCSRF(t, session, fmt.Sprintf("%s/pulls/%d", baseRepo.FullName(), issue.Index)),
 | |
| 				"status": "reopen",
 | |
| 			})
 | |
| 			return session.MakeRequest(t, req, expectedStatus)
 | |
| 		}
 | |
| 
 | |
| 		restoreBranch := func(t *testing.T, repoName, branchName string, branchID int64) {
 | |
| 			t.Helper()
 | |
| 
 | |
| 			link := fmt.Sprintf("/%s/branches", repoName)
 | |
| 			req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/restore?branch_id=%d&name=%s", link, branchID, branchName), map[string]string{
 | |
| 				"_csrf": GetCSRF(t, session, link),
 | |
| 			})
 | |
| 			session.MakeRequest(t, req, http.StatusOK)
 | |
| 
 | |
| 			flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
 | |
| 			assert.NotNil(t, flashCookie)
 | |
| 			assert.Contains(t, flashCookie.Value, "success%3DBranch%2B%2522"+branchName+"%2522%2Bhas%2Bbeen%2Brestored.")
 | |
| 		}
 | |
| 
 | |
| 		deleteBranch := func(t *testing.T, repoName, branchName string) {
 | |
| 			t.Helper()
 | |
| 
 | |
| 			link := fmt.Sprintf("/%s/branches", repoName)
 | |
| 			req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/delete?name=%s", link, branchName), map[string]string{
 | |
| 				"_csrf": GetCSRF(t, session, link),
 | |
| 			})
 | |
| 			session.MakeRequest(t, req, http.StatusOK)
 | |
| 
 | |
| 			flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
 | |
| 			assert.NotNil(t, flashCookie)
 | |
| 			assert.Contains(t, flashCookie.Value, "success%3DBranch%2B%2522"+branchName+"%2522%2Bhas%2Bbeen%2Bdeleted.")
 | |
| 		}
 | |
| 
 | |
| 		type errorJSON struct {
 | |
| 			Error string `json:"errorMessage"`
 | |
| 		}
 | |
| 
 | |
| 		t.Run("Base branch deleted", func(t *testing.T) {
 | |
| 			defer tests.PrintCurrentTest(t)()
 | |
| 
 | |
| 			branch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{Name: "base-branch", RepoID: baseRepo.ID})
 | |
| 			defer func() {
 | |
| 				restoreBranch(t, baseRepo.FullName(), branch.Name, branch.ID)
 | |
| 			}()
 | |
| 
 | |
| 			deleteBranch(t, baseRepo.FullName(), branch.Name)
 | |
| 			resp := reopenPR(t, http.StatusBadRequest)
 | |
| 
 | |
| 			var errorResp errorJSON
 | |
| 			DecodeJSON(t, resp, &errorResp)
 | |
| 			assert.EqualValues(t, translation.NewLocale("en-US").Tr("repo.pulls.reopen_failed.base_branch"), errorResp.Error)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("Head branch deleted", func(t *testing.T) {
 | |
| 			defer tests.PrintCurrentTest(t)()
 | |
| 
 | |
| 			branch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{Name: "head-branch", RepoID: headRepo.ID})
 | |
| 			defer func() {
 | |
| 				restoreBranch(t, headRepo.FullName(), branch.Name, branch.ID)
 | |
| 			}()
 | |
| 
 | |
| 			deleteBranch(t, headRepo.FullName(), branch.Name)
 | |
| 			resp := reopenPR(t, http.StatusBadRequest)
 | |
| 
 | |
| 			var errorResp errorJSON
 | |
| 			DecodeJSON(t, resp, &errorResp)
 | |
| 			assert.EqualValues(t, translation.NewLocale("en-US").Tr("repo.pulls.reopen_failed.head_branch"), errorResp.Error)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("Normal", func(t *testing.T) {
 | |
| 			defer tests.PrintCurrentTest(t)()
 | |
| 
 | |
| 			reopenPR(t, http.StatusOK)
 | |
| 		})
 | |
| 	})
 | |
| }
 |