 184e068f37
			
		
	
	
	184e068f37
	
	
	
		
			
			- Fix issue dropdown breaking when currently selected issue is included in results. - Add `sort` parameter to `/issues/search` API. - Sort dropdown by relevance. - Make priority_repo_id work again. - Added E2E test. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8003 Reviewed-by: Shiny Nematoda <snematoda@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Danko Aleksejevs <danko@very.lv> Co-committed-by: Danko Aleksejevs <danko@very.lv>
		
			
				
	
	
		
			192 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package e2e
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/hex"
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"regexp"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"forgejo.org/models/unittest"
 | |
| 	user_model "forgejo.org/models/user"
 | |
| 	"forgejo.org/modules/json"
 | |
| 	modules_session "forgejo.org/modules/session"
 | |
| 	"forgejo.org/modules/setting"
 | |
| 	"forgejo.org/modules/util"
 | |
| 	"forgejo.org/tests"
 | |
| 
 | |
| 	"code.forgejo.org/go-chi/session"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| var rootPathRe = regexp.MustCompile("\\[repository\\]\nROOT\\s=\\s.*")
 | |
| 
 | |
| func onForgejoRunTB(t testing.TB, callback func(testing.TB, *url.URL), prepare ...bool) {
 | |
| 	if len(prepare) == 0 || prepare[0] {
 | |
| 		defer tests.PrepareTestEnv(t, 1)()
 | |
| 	}
 | |
| 	createSessions(t)
 | |
| 
 | |
| 	s := http.Server{
 | |
| 		Handler: testE2eWebRoutes,
 | |
| 	}
 | |
| 
 | |
| 	u, err := url.Parse(setting.AppURL)
 | |
| 	require.NoError(t, err)
 | |
| 	listener, err := net.Listen("tcp", u.Host)
 | |
| 	i := 0
 | |
| 	for err != nil && i <= 10 {
 | |
| 		time.Sleep(100 * time.Millisecond)
 | |
| 		listener, err = net.Listen("tcp", u.Host)
 | |
| 		i++
 | |
| 	}
 | |
| 	require.NoError(t, err)
 | |
| 	u.Host = listener.Addr().String()
 | |
| 
 | |
| 	// Override repository root in config.
 | |
| 	conf, err := os.ReadFile(setting.CustomConf)
 | |
| 	require.NoError(t, err)
 | |
| 	require.NoError(t, os.WriteFile(setting.CustomConf, rootPathRe.ReplaceAll(conf, []byte("[repository]\nROOT = "+setting.RepoRootPath)), 0o644))
 | |
| 
 | |
| 	defer func() {
 | |
| 		require.NoError(t, os.WriteFile(setting.CustomConf, conf, 0o644))
 | |
| 		ctx, cancel := context.WithTimeout(t.Context(), 2*time.Minute)
 | |
| 		s.Shutdown(ctx)
 | |
| 		cancel()
 | |
| 	}()
 | |
| 
 | |
| 	go s.Serve(listener)
 | |
| 	// Started by config go ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs)
 | |
| 
 | |
| 	callback(t, u)
 | |
| }
 | |
| 
 | |
| func onForgejoRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
 | |
| 	onForgejoRunTB(t, func(t testing.TB, u *url.URL) {
 | |
| 		callback(t.(*testing.T), u)
 | |
| 	}, prepare...)
 | |
| }
 | |
| 
 | |
| func createSessions(t testing.TB) {
 | |
| 	t.Helper()
 | |
| 	// copied from playwright.config.ts
 | |
| 	browsers := []string{
 | |
| 		"chromium",
 | |
| 		"firefox",
 | |
| 		"webkit",
 | |
| 		"Mobile Chrome",
 | |
| 		"Mobile Safari",
 | |
| 	}
 | |
| 	scopes := []string{
 | |
| 		"shared",
 | |
| 	}
 | |
| 	users := []string{
 | |
| 		"user1",
 | |
| 		"user2",
 | |
| 		"user11",
 | |
| 		"user12",
 | |
| 		"user18",
 | |
| 		"user29",
 | |
| 		"user40",
 | |
| 	}
 | |
| 
 | |
| 	authState := filepath.Join(filepath.Dir(setting.AppPath), "tests", "e2e", ".auth")
 | |
| 	err := os.RemoveAll(authState)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	err = os.MkdirAll(authState, os.ModePerm)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	createSessionCookie := stateHelper(t)
 | |
| 
 | |
| 	for _, user := range users {
 | |
| 		u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: strings.ToLower(user)})
 | |
| 		for _, browser := range browsers {
 | |
| 			for _, scope := range scopes {
 | |
| 				stateFile := strings.ReplaceAll(strings.ToLower(fmt.Sprintf("state-%s-%s-%s.json", browser, user, scope)), " ", "-")
 | |
| 				createSessionCookie(filepath.Join(authState, stateFile), u)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func stateHelper(t testing.TB) func(stateFile string, user *user_model.User) {
 | |
| 	type Cookie struct {
 | |
| 		Name     string `json:"name"`
 | |
| 		Value    string `json:"value"`
 | |
| 		Domain   string `json:"domain"`
 | |
| 		Path     string `json:"path"`
 | |
| 		Expires  int    `json:"expires"`
 | |
| 		HTTPOnly bool   `json:"httpOnly"`
 | |
| 		Secure   bool   `json:"secure"`
 | |
| 		SameSite string `json:"sameSite"`
 | |
| 	}
 | |
| 
 | |
| 	type BrowserState struct {
 | |
| 		Cookies []Cookie `json:"cookies"`
 | |
| 		Origins []string `json:"origins"`
 | |
| 	}
 | |
| 
 | |
| 	options := session.Options{
 | |
| 		Provider:       setting.SessionConfig.Provider,
 | |
| 		ProviderConfig: setting.SessionConfig.ProviderConfig,
 | |
| 		CookieName:     setting.SessionConfig.CookieName,
 | |
| 		CookiePath:     setting.SessionConfig.CookiePath,
 | |
| 		Gclifetime:     setting.SessionConfig.Gclifetime,
 | |
| 		Maxlifetime:    setting.SessionConfig.Maxlifetime,
 | |
| 		Secure:         setting.SessionConfig.Secure,
 | |
| 		SameSite:       setting.SessionConfig.SameSite,
 | |
| 		Domain:         setting.SessionConfig.Domain,
 | |
| 	}
 | |
| 
 | |
| 	opt := session.PrepareOptions([]session.Options{options})
 | |
| 
 | |
| 	vsp := modules_session.VirtualSessionProvider{}
 | |
| 	err := vsp.Init(opt.Maxlifetime, opt.ProviderConfig)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	return func(stateFile string, user *user_model.User) {
 | |
| 		sessionID := hex.EncodeToString(util.CryptoRandomBytes(int64(opt.IDLength) / 2))
 | |
| 
 | |
| 		s, err := vsp.Read(sessionID)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		err = s.Set("uid", user.ID)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		err = s.Release()
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		state := BrowserState{
 | |
| 			Cookies: []Cookie{
 | |
| 				{
 | |
| 					Name:     opt.CookieName,
 | |
| 					Value:    sessionID,
 | |
| 					Domain:   setting.Domain,
 | |
| 					Path:     "/",
 | |
| 					Expires:  -1,
 | |
| 					HTTPOnly: true,
 | |
| 					Secure:   false,
 | |
| 					SameSite: "Lax",
 | |
| 				},
 | |
| 			},
 | |
| 			Origins: []string{},
 | |
| 		}
 | |
| 
 | |
| 		jsonData, err := json.Marshal(state)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		err = os.WriteFile(stateFile, jsonData, 0o644)
 | |
| 		require.NoError(t, err)
 | |
| 	}
 | |
| }
 |