From 87687e35f66114bb8caf26830be9eb84c70b1e52 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 3 Apr 2022 18:06:30 +0200 Subject: [PATCH 1/3] play around with default resolver tests --- .../betterttv/emote_resolver_test.go | 6 - .../resolvers/default/link_resolver_test.go | 120 ++++++++++++++++++ internal/resolvers/default/model_test.go | 56 ++++++++ pkg/utils/string.go | 2 +- pkg/utils/string_test.go | 2 +- 5 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 internal/resolvers/default/link_resolver_test.go create mode 100644 internal/resolvers/default/model_test.go diff --git a/internal/resolvers/betterttv/emote_resolver_test.go b/internal/resolvers/betterttv/emote_resolver_test.go index a0be9aa9..c8cafc6c 100644 --- a/internal/resolvers/betterttv/emote_resolver_test.go +++ b/internal/resolvers/betterttv/emote_resolver_test.go @@ -93,8 +93,6 @@ func TestEmoteResolver(t *testing.T) { }, } - const q = `SELECT value FROM cache WHERE key=$1` - for _, test := range tests { c.Run(test.label, func(c *qt.C) { outputBytes, outputError := resolver.Run(ctx, test.inputURL, test.inputReq) @@ -141,8 +139,6 @@ func TestEmoteResolver(t *testing.T) { }, } - const q = `SELECT value FROM cache WHERE key=$1` - for _, test := range tests { c.Run(test.label, func(c *qt.C) { rows := pgxmock.NewRows([]string{"value"}).AddRow(test.expectedBytes) @@ -194,8 +190,6 @@ func TestEmoteResolver(t *testing.T) { }, } - const q = `SELECT value FROM cache WHERE key=$1` - for _, test := range tests { c.Run(test.label, func(c *qt.C) { pool.ExpectQuery("SELECT").WillReturnError(pgx.ErrNoRows) diff --git a/internal/resolvers/default/link_resolver_test.go b/internal/resolvers/default/link_resolver_test.go new file mode 100644 index 00000000..b8afa382 --- /dev/null +++ b/internal/resolvers/default/link_resolver_test.go @@ -0,0 +1,120 @@ +package defaultresolver + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + "regexp" + "testing" + + "github.com/Chatterino/api/internal/logger" + "github.com/Chatterino/api/pkg/config" + "github.com/Chatterino/api/pkg/resolver" + qt "github.com/frankban/quicktest" + "github.com/go-chi/chi/v5" + "github.com/jackc/pgx/v4" + "github.com/pashagolub/pgxmock" +) + +func newRequest(t *testing.T, ctx context.Context, method string, url string, payload io.Reader) *http.Request { + req, err := http.NewRequestWithContext(ctx, method, url, payload) + if err != nil { + t.Fatal("Unable to create request") + } + + return req +} + +func newLinkResolverRequest(t *testing.T, ctx context.Context, method string, u string, payload io.Reader) *http.Request { + finalURL := "/link_resolver/" + url.QueryEscape(u) + fmt.Println("Final URL", finalURL) + req, err := http.NewRequestWithContext(ctx, method, finalURL, payload) + if err != nil { + t.Fatal("Unable to create request") + } + + return req +} + +func TestLinkResolver(t *testing.T) { + ctx := logger.OnContext(context.Background(), logger.NewTest()) + c := qt.New(t) + + cfg := config.APIConfig{ + MaxContentLength: 1024, + } + pool, _ := pgxmock.NewPool() + + resolver.InitializeStaticResponses(ctx, cfg) + + router := chi.NewRouter() + + r := New(ctx, cfg, pool, nil) + + router.Get("/link_resolver/{url}", r.HandleRequest) + router.Get("/thumbnail/{url}", r.HandleThumbnailRequest) + + var resolverResponses = map[string]string{} + + resolverResponses["/"] = "/ titlexD" + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if response, ok := resolverResponses[r.URL.Path]; ok { + w.Write([]byte(response)) + return + } + http.Error(w, http.StatusText(404), 404) + })) + defer ts.Close() + + c.Run("Request", func(c *qt.C) { + tests := []struct { + inputReq *http.Request + inputLinkKey string + expected resolver.Response + }{ + { + inputReq: newLinkResolverRequest(t, ctx, "GET", ts.URL, nil), + inputLinkKey: ts.URL, + expected: resolver.Response{ + Status: 200, + Link: ts.URL, + Tooltip: `.*`, + }, + }, + } + + for _, test := range tests { + c.Run("", func(c *qt.C) { + respRec := httptest.NewRecorder() + + pool.ExpectQuery("SELECT").WillReturnError(pgx.ErrNoRows) + pool.ExpectExec("INSERT INTO cache"). + WithArgs("default:link:"+test.inputLinkKey, pgxmock.AnyArg(), pgxmock.AnyArg()). + WillReturnResult(pgxmock.NewResult("INSERT", 1)) + + router.ServeHTTP(respRec, test.inputReq) + resp := respRec.Result() + response := resolver.Response{} + err := json.NewDecoder(resp.Body).Decode(&response) + c.Assert(err, qt.IsNil) + + c.Assert(response.Status, qt.Equals, test.expected.Status) + c.Assert(response.Link, qt.Equals, test.expected.Link) + + unescapedTooltip, err := url.QueryUnescape(response.Tooltip) + c.Assert(err, qt.IsNil) + + fmt.Println(unescapedTooltip) + fmt.Println(test.expected.Tooltip) + c.Assert("asd\nasd", qt.Matches, regexp.MustCompile(`.*`)) + + c.Assert(pool.ExpectationsWereMet(), qt.IsNil) + }) + } + }) +} diff --git a/internal/resolvers/default/model_test.go b/internal/resolvers/default/model_test.go new file mode 100644 index 00000000..ef6f1fc1 --- /dev/null +++ b/internal/resolvers/default/model_test.go @@ -0,0 +1,56 @@ +package defaultresolver + +import ( + "testing" + + qt "github.com/frankban/quicktest" +) + +func TestTooltipData(t *testing.T) { + c := qt.New(t) + + c.Run("Truncate", func(c *qt.C) { + tests := []struct { + input tooltipData + expected tooltipData + }{ + { + input: tooltipData{ + Title: "foo", + Description: "bar", + }, + expected: tooltipData{ + Title: "foo", + Description: "bar", + }, + }, + { + input: tooltipData{ + Title: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy", + Description: "bar", + }, + expected: tooltipData{ + Title: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy", + Description: "bar", + }, + }, + { + input: tooltipData{ + Title: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyz", + Description: "bar", + }, + expected: tooltipData{ + Title: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…", + Description: "bar", + }, + }, + } + + for _, test := range tests { + c.Run("", func(c *qt.C) { + test.input.Truncate() + c.Assert(test.input, qt.DeepEquals, test.expected) + }) + } + }) +} diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 88d20488..e803f4e2 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -5,7 +5,7 @@ import "strings" // TruncateString truncates string down to the maximum length with a unicode triple dot if truncation took place func TruncateString(s string, maxLength int) string { runes := []rune(s) - if len(runes) < maxLength { + if len(runes) <= maxLength { return s } diff --git a/pkg/utils/string_test.go b/pkg/utils/string_test.go index 7363123a..e23f1991 100644 --- a/pkg/utils/string_test.go +++ b/pkg/utils/string_test.go @@ -22,7 +22,7 @@ func TestTruncateString(t *testing.T) { { input: "foobar", maxLength: 6, - expectedOutput: "fooba…", + expectedOutput: "foobar", }, { input: "foobar", From 3a0353253a2a9d66d4014afe8c1065cbdd0fac18 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 23 Apr 2022 21:10:52 +0200 Subject: [PATCH 2/3] Fix tests with custom regexp checker --- .../resolvers/default/link_resolver_test.go | 20 +++++--- .../resolvers/default/regexpchecker_test.go | 46 +++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 internal/resolvers/default/regexpchecker_test.go diff --git a/internal/resolvers/default/link_resolver_test.go b/internal/resolvers/default/link_resolver_test.go index b8afa382..beda768a 100644 --- a/internal/resolvers/default/link_resolver_test.go +++ b/internal/resolvers/default/link_resolver_test.go @@ -81,9 +81,14 @@ func TestLinkResolver(t *testing.T) { inputReq: newLinkResolverRequest(t, ctx, "GET", ts.URL, nil), inputLinkKey: ts.URL, expected: resolver.Response{ - Status: 200, - Link: ts.URL, - Tooltip: `.*`, + Status: 200, + Link: ts.URL, + Tooltip: `
+ +/ title
+ + +URL: http://127\.0\.0\.1:[\d]{2,7}
`, }, }, } @@ -109,9 +114,12 @@ func TestLinkResolver(t *testing.T) { unescapedTooltip, err := url.QueryUnescape(response.Tooltip) c.Assert(err, qt.IsNil) - fmt.Println(unescapedTooltip) - fmt.Println(test.expected.Tooltip) - c.Assert("asd\nasd", qt.Matches, regexp.MustCompile(`.*`)) + if test.expected.Tooltip != "" { + c.Assert(unescapedTooltip, MatchesRegexp, regexp.MustCompile(test.expected.Tooltip), qt.Commentf("%s does not match %s", unescapedTooltip, test.expected.Tooltip)) + } + if test.expected.Message != "" { + c.Assert(response.Message, qt.Matches, test.expected.Message, qt.Commentf("%s does not match %s", response.Message, test.expected.Message)) + } c.Assert(pool.ExpectationsWereMet(), qt.IsNil) }) diff --git a/internal/resolvers/default/regexpchecker_test.go b/internal/resolvers/default/regexpchecker_test.go new file mode 100644 index 00000000..f76f36ff --- /dev/null +++ b/internal/resolvers/default/regexpchecker_test.go @@ -0,0 +1,46 @@ +package defaultresolver + +import ( + "errors" + "fmt" + "regexp" + + qt "github.com/frankban/quicktest" +) + +type argNames []string + +func (a argNames) ArgNames() []string { + return a +} + +var MatchesRegexp qt.Checker = ®expChecker{ + argNames: []string{"got value", "regexp"}, +} + +type regexpChecker struct { + argNames +} + +// match checks that the given error message matches the given pattern. +func match(got string, pattern *regexp.Regexp, msg string, note func(key string, value interface{})) error { + if pattern.MatchString(got) { + return nil + } + + return errors.New(msg) +} + +func (c *regexpChecker) Check(got interface{}, args []interface{}, note func(key string, value interface{})) error { + switch pattern := args[0].(type) { + case *regexp.Regexp: + switch v := got.(type) { + case string: + return match(v, pattern, "value does not match regexp", note) + case fmt.Stringer: + return match(v.String(), pattern, "value.String() does not match regexp", note) + } + return qt.BadCheckf("value is not a string or a fmt.Stringer") + } + return qt.BadCheckf("pattern is not a *regexp.Regexp") +} From c90b16ca7618756b529660daae372bffae1b3e0c Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 23 Apr 2022 21:32:35 +0200 Subject: [PATCH 3/3] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 105990ca..b2e14ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Dev: Improve SevenTV tests. (#294) - Dev: Improve FrankerFaceZ tests. (#295) - Dev: Improve Livestreamfails tests. (#297, #301) +- Dev: Improve default resolver tests. (#300) ## 1.2.3