From 6a4421f8e15b4f0bede153730f12e4027d9aa3b7 Mon Sep 17 00:00:00 2001 From: julien0221 <68500525+julien0221@users.noreply.github.com> Date: Tue, 13 Apr 2021 01:32:52 +0100 Subject: [PATCH] Whitespace is not trimmed from the end of query strings (#1263) * fixed whitespace not trimmed query string * fixed whitespace trimming on backend * added query trim tests and fixed double space --- pkg/sqlite/scene_test.go | 47 ++++++++++++++++++- pkg/sqlite/setup_test.go | 16 ++++++- pkg/sqlite/sql.go | 7 ++- .../src/components/Changelog/versions/v070.md | 1 + ui/v2.5/src/models/list-filter/filter.ts | 2 +- 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/pkg/sqlite/scene_test.go b/pkg/sqlite/scene_test.go index cb4927523..c61f71eb0 100644 --- a/pkg/sqlite/scene_test.go +++ b/pkg/sqlite/scene_test.go @@ -1164,7 +1164,7 @@ func TestSceneQuerySorting(t *testing.T) { lastScene := scenes[len(scenes)-1] assert.Equal(t, sceneIDs[0], firstScene.ID) - assert.Equal(t, sceneIDs[len(sceneIDs)-1], lastScene.ID) + assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], lastScene.ID) // sort in descending order direction = models.SortDirectionEnumDesc @@ -1173,7 +1173,7 @@ func TestSceneQuerySorting(t *testing.T) { firstScene = scenes[0] lastScene = scenes[len(scenes)-1] - assert.Equal(t, sceneIDs[len(sceneIDs)-1], firstScene.ID) + assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], firstScene.ID) assert.Equal(t, sceneIDs[0], lastScene.ID) return nil @@ -1519,6 +1519,49 @@ func TestSceneStashIDs(t *testing.T) { } } +func TestSceneQueryQTrim(t *testing.T) { + if err := withTxn(func(r models.Repository) error { + qb := r.Scene() + + expectedID := sceneIDs[sceneIdxWithSpacedName] + + type test struct { + query string + id int + count int + } + tests := []test{ + {query: " zzz yyy ", id: expectedID, count: 1}, + {query: " \"zzz yyy xxx\" ", id: expectedID, count: 1}, + {query: "zzz", id: expectedID, count: 1}, + {query: "\" zzz yyy \"", count: 0}, + {query: "\"zzz yyy\"", count: 0}, + {query: "\" zzz yyy\"", count: 0}, + {query: "\"zzz yyy \"", count: 0}, + } + + for _, tst := range tests { + f := models.FindFilterType{ + Q: &tst.query, + } + scenes := queryScene(t, qb, nil, &f) + + assert.Len(t, scenes, tst.count) + if len(scenes) > 0 { + assert.Equal(t, tst.id, scenes[0].ID) + } + } + + findFilter := models.FindFilterType{} + scenes := queryScene(t, qb, nil, &findFilter) + assert.NotEqual(t, 0, len(scenes)) + + return nil + }); err != nil { + t.Error(err.Error()) + } +} + // TODO Update // TODO IncrementOCounter // TODO DecrementOCounter diff --git a/pkg/sqlite/setup_test.go b/pkg/sqlite/setup_test.go index de5930fd4..7996f9516 100644 --- a/pkg/sqlite/setup_test.go +++ b/pkg/sqlite/setup_test.go @@ -20,6 +20,10 @@ import ( "github.com/stashapp/stash/pkg/utils" ) +const ( + spacedSceneTitle = "zzz yyy xxx" +) + const ( sceneIdxWithMovie = iota sceneIdxWithGallery @@ -33,6 +37,7 @@ const ( sceneIdxWithMarker sceneIdxWithPerformerTag sceneIdxWithPerformerTwoTags + sceneIdxWithSpacedName // new indexes above lastSceneIdx @@ -452,6 +457,15 @@ func getSceneNullStringValue(index int, field string) sql.NullString { return getPrefixedNullStringValue("scene", index, field) } +func getSceneTitle(index int) string { + switch index { + case sceneIdxWithSpacedName: + return spacedSceneTitle + default: + return getSceneStringValue(index, titleField) + } +} + func getRating(index int) sql.NullInt64 { rating := index % 6 return sql.NullInt64{Int64: int64(rating), Valid: rating > 0} @@ -493,7 +507,7 @@ func createScenes(sqb models.SceneReaderWriter, n int) error { for i := 0; i < n; i++ { scene := models.Scene{ Path: getSceneStringValue(i, pathField), - Title: sql.NullString{String: getSceneStringValue(i, titleField), Valid: true}, + Title: sql.NullString{String: getSceneTitle(i), Valid: true}, Checksum: sql.NullString{String: getSceneStringValue(i, checksumField), Valid: true}, Details: sql.NullString{String: getSceneStringValue(i, "Details"), Valid: true}, URL: getSceneNullStringValue(i, urlField), diff --git a/pkg/sqlite/sql.go b/pkg/sqlite/sql.go index bbd8fde13..b683e1a07 100644 --- a/pkg/sqlite/sql.go +++ b/pkg/sqlite/sql.go @@ -4,6 +4,7 @@ import ( "database/sql" "fmt" "math/rand" + "regexp" "strconv" "strings" @@ -116,10 +117,12 @@ func getSearchBinding(columns []string, q string, not bool) (string, []interface notStr = " NOT" binaryType = " AND " } - - queryWords := strings.Split(q, " ") + q = strings.TrimSpace(q) trimmedQuery := strings.Trim(q, "\"") + if trimmedQuery == q { + q = regexp.MustCompile(`\s+`).ReplaceAllString(q, " ") + queryWords := strings.Split(q, " ") // Search for any word for _, word := range queryWords { for _, column := range columns { diff --git a/ui/v2.5/src/components/Changelog/versions/v070.md b/ui/v2.5/src/components/Changelog/versions/v070.md index f005c915a..c3bfdd6e4 100644 --- a/ui/v2.5/src/components/Changelog/versions/v070.md +++ b/ui/v2.5/src/components/Changelog/versions/v070.md @@ -17,6 +17,7 @@ * Change performer text query to search by name and alias only. ### 🐛 Bug fixes +* Fix whitespace in query string returning all objects. * Fix hang on Login page when not connected to internet. * Fix `Clear Image` button not updating image preview. * Fix processing some webp files. diff --git a/ui/v2.5/src/models/list-filter/filter.ts b/ui/v2.5/src/models/list-filter/filter.ts index 58116771b..fe775f41e 100644 --- a/ui/v2.5/src/models/list-filter/filter.ts +++ b/ui/v2.5/src/models/list-filter/filter.ts @@ -366,7 +366,7 @@ export class ListFilterModel { this.displayMode = Number.parseInt(params.disp, 10); } if (params.q) { - this.searchTerm = params.q; + this.searchTerm = params.q.trim(); } if (params.p) { this.currentPage = Number.parseInt(params.p, 10);