From c3fe2a5e3434c6fe8f28ea7960263eb15d551d2a Mon Sep 17 00:00:00 2001 From: Shiny Nematoda Date: Thu, 22 Jan 2026 06:05:16 +0100 Subject: [PATCH] [v14.0/forgejo] fix(ui): add missing translation for code search when keyword is empty string (#10970) **Backport:** https://codeberg.org/forgejo/forgejo/pulls/10964 - `CodeSearchMode` was is now set when keyword is empty - The default value for search mode should be exact, use fuzzy ONLY when fuzziness is enabled in settings (cherry picked from commit da7ce1753377ac5670e8de6672123ad789972b57) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10970 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Shiny Nematoda Co-committed-by: Shiny Nematoda --- routers/web/repo/search.go | 10 ++++-- tests/integration/repo_search_test.go | 44 +++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index c3b4d07fa0..11b6c3b218 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -69,8 +69,9 @@ func Search(ctx *context.Context) { mode := ExactSearchMode if modeStr := ctx.FormString("mode"); len(modeStr) > 0 { mode = searchModeFromString(modeStr) - } else if ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) { // for backward compatibility in links - mode = UnionSearchMode + } else if ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) && + setting.Indexer.RepoIndexerEnableFuzzy { // for backward compatibility in links + mode = FuzzySearchMode } ctx.Data["Keyword"] = keyword @@ -85,6 +86,11 @@ func Search(ctx *context.Context) { } if keyword == "" { + if setting.Indexer.RepoIndexerEnabled { + ctx.Data["CodeSearchMode"] = mode.ToIndexer().String() + } else { + ctx.Data["CodeSearchMode"] = mode.ToGitGrep().String() + } ctx.HTML(http.StatusOK, tplSearch) return } diff --git a/tests/integration/repo_search_test.go b/tests/integration/repo_search_test.go index 874970fe56..bb894b843c 100644 --- a/tests/integration/repo_search_test.go +++ b/tests/integration/repo_search_test.go @@ -83,6 +83,9 @@ func testSearchRepo(t *testing.T, indexer bool) { code_indexer.UpdateRepoIndexer(repo) } + testEmptySearch(t, indexer, true) + testEmptySearch(t, indexer, false) + testSearch(t, "/user2/glob/search?q=", []string{}, indexer) testSearch(t, "/user2/glob/search?q=loren&page=1", []string{"a.txt"}, indexer) testSearch(t, "/user2/glob/search?q=loren&page=1&mode=exact", []string{"a.txt"}, indexer) @@ -97,6 +100,30 @@ func testSearchRepo(t *testing.T, indexer bool) { testSearch(t, "/user2/glob/search?q=file5&page=1&mode=exact", []string{}, indexer) } +func testEmptySearch(t *testing.T, indexer, withFuzzy bool) { + defer test.MockVariableValue(&setting.Indexer.RepoIndexerEnableFuzzy, withFuzzy)() + req := NewRequest(t, "GET", "/user2/glob/search") + resp := MakeRequest(t, req, http.StatusOK) + + container := NewHTMLParser(t, resp.Body). + Find(".repository"). + Find(".ui.container") + + key := "search.exact" + if withFuzzy && indexer { + key = "search.fuzzy" + } + + expected := translation.NewLocale("en-US").TrString(key) + menu := container.Find(".menu[data-test-tag=fuzzy-dropdown]") + defaultOpt := menu. + Parent(). + Find(".text"). + Text() + + assert.Equal(t, expected, strings.TrimSpace(defaultOpt)) +} + func testSearch(t *testing.T, rawURL string, expected []string, indexer bool) { req := NewRequest(t, "GET", rawURL) resp := MakeRequest(t, req, http.StatusOK) @@ -131,10 +158,23 @@ func testSearch(t *testing.T, rawURL string, expected []string, indexer bool) { // testDropdownOptions verifies additional properties of dropdown options func testDropdownOptions(t *testing.T, container *goquery.Selection, options []string, locale translation.Locale) { - for _, option := range options { + tr := make([]string, len(options)) + for i, option := range options { + tr[i] = locale.TrString(fmt.Sprintf("search.%s", option)) + } + + // assert that the default value (in a .text adjacent to the menu) is a valid option + defaultOpt := container. + Find(".menu[data-test-tag=fuzzy-dropdown]"). + Parent(). + Find(".text"). + Text() + assert.Contains(t, tr, strings.TrimSpace(defaultOpt)) + + for i, option := range options { label := container.Find(fmt.Sprintf("label.item:has(input[value='%s'])", option)) name := strings.TrimSpace(label.Text()) - assert.Equal(t, name, locale.TrString(fmt.Sprintf("search.%s", option))) + assert.Equal(t, name, tr[i]) tooltip, exists := label.Attr("data-tooltip-content") assert.True(t, exists)