From 26cd1533b4209ca39112ea01aefa11f5e2548f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Sun, 11 Dec 2022 02:47:23 +0100 Subject: [PATCH] Tests[SearchMessageFTSSimple] --- server/api/handler/api.go | 4 ++++ server/api/handler/compat.go | 2 +- server/db/messages.go | 4 ++-- server/go.mod | 2 +- server/go.sum | 2 ++ server/models/messagefilter.go | 22 ++++++++++++---------- server/test/message_test.go | 21 +++++++++++++++++++-- server/test/util/common.go | 8 ++++++++ server/test/util/factory.go | 14 ++++++++++---- 9 files changed, 59 insertions(+), 20 deletions(-) diff --git a/server/api/handler/api.go b/server/api/handler/api.go index 636cca0..dad3c1f 100644 --- a/server/api/handler/api.go +++ b/server/api/handler/api.go @@ -1184,6 +1184,10 @@ func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse { ConfirmedSubscriptionBy: langext.Ptr(userid), } + if q.Filter != nil && strings.TrimSpace(*q.Filter) != "" { + filter.SearchString = langext.Ptr([]string{strings.TrimSpace(*q.Filter)}) + } + messages, npt, err := h.database.ListMessages(ctx, filter, pageSize, tok) if err != nil { return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to query messages", err) diff --git a/server/api/handler/compat.go b/server/api/handler/compat.go index f231a61..a5bf462 100644 --- a/server/api/handler/compat.go +++ b/server/api/handler/compat.go @@ -201,7 +201,7 @@ func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse { return ginresp.CompatAPIError(0, "Failed to query clients") } - fcmSet := langext.ArrAny(clients, func(i int) bool { return clients[i].FCMToken != nil }) + fcmSet := langext.ArrAny(clients, func(c models.Client) bool { return c.FCMToken != nil }) return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{ Success: true, diff --git a/server/db/messages.go b/server/db/messages.go index 4c6240e..4f59719 100644 --- a/server/db/messages.go +++ b/server/db/messages.go @@ -121,7 +121,7 @@ func (db *Database) ListMessages(ctx TxContext, filter models.MessageFilter, pag return make([]models.Message, 0), cursortoken.End(), nil } - pageCond := "" + pageCond := "1=1" if inTok.Mode == cursortoken.CTMNormal { pageCond = "timestamp_real < :tokts OR (timestamp_real = :tokts AND scn_message_id < :tokid )" } @@ -130,7 +130,7 @@ func (db *Database) ListMessages(ctx TxContext, filter models.MessageFilter, pag orderClause := "ORDER BY COALESCE(timestamp_client, timestamp_real) DESC LIMIT :lim" - sqlQuery := "SELECT " + "messages.*" + " FROM messages " + filterJoin + " WHERE ( " + filterCond + " ) AND ( " + pageCond + " ) " + orderClause + sqlQuery := "SELECT " + "messages.*" + " FROM messages " + filterJoin + " WHERE ( " + pageCond + " ) AND ( " + filterCond + " ) " + orderClause prepParams["lim"] = pageSize + 1 prepParams["tokts"] = inTok.Timestamp diff --git a/server/go.mod b/server/go.mod index 11201e1..f3c27ee 100644 --- a/server/go.mod +++ b/server/go.mod @@ -8,7 +8,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.16 github.com/rs/zerolog v1.28.0 github.com/swaggo/swag v1.8.7 - gogs.mikescher.com/BlackForestBytes/goext v0.0.32 + gogs.mikescher.com/BlackForestBytes/goext v0.0.33 ) require ( diff --git a/server/go.sum b/server/go.sum index 0ff9e69..a12ebc3 100644 --- a/server/go.sum +++ b/server/go.sum @@ -102,6 +102,8 @@ gogs.mikescher.com/BlackForestBytes/goext v0.0.31 h1:DC2RZe7/tSDDbPRbjDcYa+BLRlY gogs.mikescher.com/BlackForestBytes/goext v0.0.31/go.mod h1:/u9JtMwCP68ix4R9BJ/MT0Lm+QScmqIoyYZFKBGzv9g= gogs.mikescher.com/BlackForestBytes/goext v0.0.32 h1:DJoRBNhq4rrOBXA/nD6WEm7L3vylLkMifU9/sWEiF7M= gogs.mikescher.com/BlackForestBytes/goext v0.0.32/go.mod h1:/u9JtMwCP68ix4R9BJ/MT0Lm+QScmqIoyYZFKBGzv9g= +gogs.mikescher.com/BlackForestBytes/goext v0.0.33 h1:NQRgsEs2j8eY9V45Ynq84+F0FgBfvapOGv4JZMh0eaI= +gogs.mikescher.com/BlackForestBytes/goext v0.0.33/go.mod h1:/u9JtMwCP68ix4R9BJ/MT0Lm+QScmqIoyYZFKBGzv9g= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= diff --git a/server/models/messagefilter.go b/server/models/messagefilter.go index eb1a50a..73be803 100644 --- a/server/models/messagefilter.go +++ b/server/models/messagefilter.go @@ -46,7 +46,7 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) { joinClause += " LEFT JOIN subscriptions subs on messages.channel_id = subs.channel_id " } if f.SearchString != nil { - joinClause += " JOIN messages_fts mfts on (mfts.rowid = a.scn_message_id) " + joinClause += " JOIN messages_fts mfts on (mfts.rowid = messages.scn_message_id) " } sqlClauses := make([]string, 0) @@ -58,15 +58,6 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) { params["sub_uid"] = *f.ConfirmedSubscriptionBy } - if f.SearchString != nil { - filter := make([]string, 0) - for i, v := range *f.SearchString { - filter = append(filter, fmt.Sprintf("(messages_fts match :searchstring_%d)", i)) - params[fmt.Sprintf("searchstring_%d", i)] = v - } - sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")") - } - if f.Sender != nil { filter := make([]string, 0) for i, v := range *f.Sender { @@ -208,9 +199,20 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) { sqlClauses = append(sqlClauses, "(usr_message_id IS NOT NULL AND ("+strings.Join(filter, " OR ")+"))") } + if f.SearchString != nil { + filter := make([]string, 0) + for i, v := range *f.SearchString { + filter = append(filter, fmt.Sprintf("(messages_fts match :searchstring_%d)", i)) + params[fmt.Sprintf("searchstring_%d", i)] = v + } + sqlClauses = append(sqlClauses, "("+strings.Join(filter, " OR ")+")") + } + sqlClause := "" if len(sqlClauses) > 0 { sqlClause = strings.Join(sqlClauses, " AND ") + } else { + sqlClause = "1=1" } return sqlClause, joinClause, params, nil diff --git a/server/test/message_test.go b/server/test/message_test.go index 9d1b234..a558aca 100644 --- a/server/test/message_test.go +++ b/server/test/message_test.go @@ -2,15 +2,32 @@ package test import ( tt "blackforestbytes.com/simplecloudnotifier/test/util" + "fmt" + "github.com/gin-gonic/gin" + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "net/url" "testing" ) -func TestSearchMessageFTS(t *testing.T) { +func TestSearchMessageFTSSimple(t *testing.T) { ws, stop := tt.StartSimpleWebserver(t) defer stop() - tt.InitDefaultData(t, ws) + baseUrl := "http://127.0.0.1:" + ws.Port + data := tt.InitDefaultData(t, ws) + + type mglist struct { + Messages []gin.H `json:"messages"` + } + + msgList := tt.RequestAuthGet[mglist](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/messages?filter=%s", url.QueryEscape("Friday"))) + tt.AssertEqual(t, "msgList.len", 2, len(msgList.Messages)) + tt.AssertTrue(t, "msgList.any<1>", langext.ArrAny(msgList.Messages, func(msg gin.H) bool { return msg["title"].(string) == "Invitation" })) + tt.AssertTrue(t, "msgList.any<2>", langext.ArrAny(msgList.Messages, func(msg gin.H) bool { return msg["title"].(string) == "Important notice" })) +} + +func TestSearchMessageFTSMulti(t *testing.T) { //TODO search for messages by FTS } diff --git a/server/test/util/common.go b/server/test/util/common.go index adf8a15..4a4eb70 100644 --- a/server/test/util/common.go +++ b/server/test/util/common.go @@ -56,6 +56,14 @@ func AssertEqual(t *testing.T, key string, expected any, actual any) { } } +func AssertTrue(t *testing.T, key string, v bool) { + if !v { + t.Errorf("AssertTrue(%s) failed", key) + t.Error(string(debug.Stack())) + t.FailNow() + } +} + func AssertNotEqual(t *testing.T, key string, expected any, actual any) { if expected == actual { t.Errorf("Value [%s] does not differ (%T <-> %T):\n", key, expected, actual) diff --git a/server/test/util/factory.go b/server/test/util/factory.go index 82b9e67..67179c6 100644 --- a/server/test/util/factory.go +++ b/server/test/util/factory.go @@ -58,7 +58,7 @@ type clientex struct { FCMTok string } -type userdat struct { +type Userdat struct { UID int64 SendKey string AdminKey string @@ -266,7 +266,11 @@ var messageExamples = []msgex{ {11, "Promotions", "", P2, SKEY, "Summer Clearance: Save Up to 75% on Your Favorite Products", "It's time for our annual summer clearance sale! Save up to 75% on your favorite products, from clothing and accessories to home decor and more.", timeext.FromHours(1.87)}, } -func InitDefaultData(t *testing.T, ws *logic.Application) { +type DefData struct { + User []Userdat +} + +func InitDefaultData(t *testing.T, ws *logic.Application) DefData { // set logger to buffer, only output if error occured success := false @@ -280,7 +284,7 @@ func InitDefaultData(t *testing.T, ws *logic.Application) { baseUrl := "http://127.0.0.1:" + ws.Port - users := make([]userdat, 0, len(userExamples)) + users := make([]Userdat, 0, len(userExamples)) for _, uex := range userExamples { body := gin.H{} @@ -306,7 +310,7 @@ func InitDefaultData(t *testing.T, ws *logic.Application) { admintok0 := user0["admin_key"].(string) AssertMultiNonEmpty(t, "user0", uid0, readtok0, sendtok0, admintok0) - users = append(users, userdat{ + users = append(users, Userdat{ UID: uid0, SendKey: sendtok0, AdminKey: admintok0, @@ -361,6 +365,8 @@ func InitDefaultData(t *testing.T, ws *logic.Application) { } success = true + + return DefData{User: users} } func lipsum(seed int64, paracount int) string {