From dd1510697d9a4ecbd3a9b331d5b6fcdfc8476012 Mon Sep 17 00:00:00 2001 From: STF 5 Date: Wed, 11 Jun 2025 11:41:16 +0900 Subject: [PATCH 1/3] fix(server): trim whitespace from user name or email input Issue: #225 --- server/internal/adapter/gql/loader_user.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/internal/adapter/gql/loader_user.go b/server/internal/adapter/gql/loader_user.go index 4dea0df810..c9c32bb18c 100644 --- a/server/internal/adapter/gql/loader_user.go +++ b/server/internal/adapter/gql/loader_user.go @@ -2,6 +2,7 @@ package gql import ( "context" + "strings" "github.com/reearth/reearth/server/internal/adapter/gql/gqldataloader" "github.com/reearth/reearth/server/internal/adapter/gql/gqlmodel" @@ -38,6 +39,10 @@ func (c *UserLoader) Fetch(ctx context.Context, ids []gqlmodel.ID) ([]*gqlmodel. } func (c *UserLoader) SearchUser(ctx context.Context, nameOrEmail string) (*gqlmodel.User, error) { + + trimmed := strings.TrimSpace(nameOrEmail) + nameOrEmail = trimmed + res, err := c.usecase.SearchUser(ctx, nameOrEmail) if err != nil { return nil, err From 57d245e8005c3b3ed8e146ecbe06d349a176278e Mon Sep 17 00:00:00 2001 From: STF 5 Date: Wed, 11 Jun 2025 18:29:53 +0900 Subject: [PATCH 2/3] =?UTF-8?q?test(server):=20add=20whitespace=E2=80=90tr?= =?UTF-8?q?imming=20case=20to=20TestSearchUser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/e2e/gql_user_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/e2e/gql_user_test.go b/server/e2e/gql_user_test.go index d13586df88..f8b8c1905c 100644 --- a/server/e2e/gql_user_test.go +++ b/server/e2e/gql_user_test.go @@ -150,6 +150,15 @@ func TestSearchUser(t *testing.T) { o.Value("name").String().IsEqual("e2e") o.Value("email").String().IsEqual("e2e@e2e.com") + query = fmt.Sprintf(` { searchUser(nameOrEmail: "%s"){ id name email } }`, " e2e") + request = GraphQLRequest{ + Query: query, + } + o = Request(e, uId1.String(), request).Object().Value("data").Object().Value("searchUser").Object() + o.Value("id").String().IsEqual(uId1.String()) + o.Value("name").String().IsEqual("e2e") + o.Value("email").String().IsEqual("e2e@e2e.com") + query = fmt.Sprintf(` { searchUser(nameOrEmail: "%s"){ id name email } }`, "notfound") request = GraphQLRequest{ Query: query, From c588efcfe870dee37c89eb410c4d7cab490c7fbf Mon Sep 17 00:00:00 2001 From: STF 5 Date: Thu, 12 Jun 2025 19:48:43 +0900 Subject: [PATCH 3/3] test(server): convert TestSearchUser to table-driven --- server/e2e/gql_user_test.go | 64 ++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/server/e2e/gql_user_test.go b/server/e2e/gql_user_test.go index f8b8c1905c..b452e439dd 100644 --- a/server/e2e/gql_user_test.go +++ b/server/e2e/gql_user_test.go @@ -141,32 +141,46 @@ func TestDeleteMe(t *testing.T) { func TestSearchUser(t *testing.T) { e, _ := StartGQLServerAndRepos(t, baseSeederUser) - query := fmt.Sprintf(` { searchUser(nameOrEmail: "%s"){ id name email } }`, "e2e") - request := GraphQLRequest{ - Query: query, - } - o := Request(e, uId1.String(), request).Object().Value("data").Object().Value("searchUser").Object() - o.Value("id").String().IsEqual(uId1.String()) - o.Value("name").String().IsEqual("e2e") - o.Value("email").String().IsEqual("e2e@e2e.com") - - query = fmt.Sprintf(` { searchUser(nameOrEmail: "%s"){ id name email } }`, " e2e") - request = GraphQLRequest{ - Query: query, - } - o = Request(e, uId1.String(), request).Object().Value("data").Object().Value("searchUser").Object() - o.Value("id").String().IsEqual(uId1.String()) - o.Value("name").String().IsEqual("e2e") - o.Value("email").String().IsEqual("e2e@e2e.com") - - query = fmt.Sprintf(` { searchUser(nameOrEmail: "%s"){ id name email } }`, "notfound") - request = GraphQLRequest{ - Query: query, - } - resp := Request(e, uId1.String(), request).Object() - resp.Value("data").Object().Value("searchUser").IsNull() - resp.NotContainsKey("errors") // not exist + tests := []struct { + name string + input string + wantFound bool + }{ + { + name: "exact match", + input: "e2e", + wantFound: true, + }, + { + name: "trimming space", + input: " e2e", + wantFound: true, + }, + { + name: "not found", + input: "notfound", + wantFound: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + query := fmt.Sprintf(`{ searchUser(nameOrEmail: "%s"){ id name email } }`,tt.input) + request := GraphQLRequest{ Query: query } + resp := Request(e, uId1.String(), request).Object().Value("data").Object() + + if tt.wantFound { + o := resp.Value("searchUser").Object() + o.Value("id").String().IsEqual(uId1.String()) + o.Value("name").String().IsEqual("e2e") + o.Value("email").String().IsEqual("e2e@e2e.com") + } else { + resp.Value("searchUser").IsNull() + resp.NotContainsKey("errors") + } + }) + } } func TestNode(t *testing.T) {