From 1f1290773c57fc5d5f3c6ab5b44c27ab8cd45e7f Mon Sep 17 00:00:00 2001 From: Dmitry Verkhoturov Date: Wed, 28 Sep 2022 22:58:51 +0200 Subject: [PATCH] fix RPC engine work with ListFlags method Fixes the following conversion problem for BlockedUser: ``` panic: interface conversion: interface {} is map[string]interface {}, not store.BlockedUser [recovered] ``` Resolves #1475. --- .../_example/memory_store/server/data_test.go | 49 ++++++++++++++++--- backend/app/store/engine/remote.go | 36 ++++++++++++-- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/backend/_example/memory_store/server/data_test.go b/backend/_example/memory_store/server/data_test.go index d99177fd2a..dcc56f6339 100644 --- a/backend/_example/memory_store/server/data_test.go +++ b/backend/_example/memory_store/server/data_test.go @@ -198,25 +198,62 @@ func TestRPC_listFlagsHndl(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "123456", id) - flagReq := engine.FlagRequest{ + // verify user + verifyFlagReq := engine.FlagRequest{ Flag: engine.Verified, UserID: "u1", Locator: store.Locator{ SiteID: "test-site", }, } - flags, err := re.ListFlags(flagReq) + flags, err := re.ListFlags(verifyFlagReq) require.NoError(t, err) - assert.Equal(t, []interface{}{}, flags) + assert.Empty(t, flags) - flagReq.Update = engine.FlagTrue - status, err := re.Flag(flagReq) + verifyFlagReq.Update = engine.FlagTrue + status, err := re.Flag(verifyFlagReq) require.NoError(t, err) assert.Equal(t, true, status) - flags, err = re.ListFlags(flagReq) + flags, err = re.ListFlags(verifyFlagReq) require.NoError(t, err) assert.Equal(t, []interface{}{"u1"}, flags) + var verifiedUsers []string + for _, v := range flags { + verifiedUsers = append(verifiedUsers, v.(string)) + } + assert.Equal(t, []string{"u1"}, verifiedUsers) + + // block user + blockFlagReq := engine.FlagRequest{ + Flag: engine.Blocked, + UserID: "u1", + Locator: store.Locator{ + SiteID: "test-site", + }, + TTL: time.Hour, + } + flags, err = re.ListFlags(blockFlagReq) + require.NoError(t, err) + assert.Empty(t, flags) + + blockFlagReq.Update = engine.FlagTrue + status, err = re.Flag(blockFlagReq) + require.NoError(t, err) + assert.Equal(t, true, status) + + flags, err = re.ListFlags(blockFlagReq) + require.NoError(t, err) + assert.NotEmpty(t, flags) + var blockedUsers []store.BlockedUser + for _, v := range flags { + blockedUsers = append(blockedUsers, v.(store.BlockedUser)) + } + require.Equal(t, 1, len(blockedUsers)) + blockedUserInfo := blockedUsers[0] + assert.Equal(t, "u1", blockedUserInfo.ID) + assert.True(t, blockedUserInfo.Until.After(time.Now().Add(time.Minute*59)), "blocked duration is more than 59m away") + assert.True(t, blockedUserInfo.Until.Before(time.Now().Add(time.Minute*61)), "blocked duration is less than 61m away") } func TestRPC_userDetailHndl(t *testing.T) { diff --git a/backend/app/store/engine/remote.go b/backend/app/store/engine/remote.go index 2ebee80949..4fcab5f2b5 100644 --- a/backend/app/store/engine/remote.go +++ b/backend/app/store/engine/remote.go @@ -71,14 +71,44 @@ func (r *RPC) Flag(req FlagRequest) (status bool, err error) { return status, err } +func unmarshalString(data []byte) ([]interface{}, error) { + var strings []string + if err := json.Unmarshal(data, &strings); err != nil { + return nil, err + } + list := make([]interface{}, 0, len(strings)) + for _, w := range strings { + list = append(list, w) + } + return list, nil +} + +func unmarshalBlockedUser(data []byte) ([]interface{}, error) { + var blockedUsers []store.BlockedUser + if err := json.Unmarshal(data, &blockedUsers); err != nil { + return nil, err + } + list := make([]interface{}, 0, len(blockedUsers)) + for _, w := range blockedUsers { + list = append(list, w) + } + return list, nil +} + // ListFlags get list of flagged keys, like blocked & verified user -func (r *RPC) ListFlags(req FlagRequest) (list []interface{}, err error) { +func (r *RPC) ListFlags(req FlagRequest) ([]interface{}, error) { resp, err := r.Call("store.list_flags", req) if err != nil { return nil, err } - err = json.Unmarshal(*resp.Result, &list) - return list, err + // try []store.BlockedUser + list, err := unmarshalBlockedUser(*resp.Result) + if err == nil { + return list, err + } + + // try []strings + return unmarshalString(*resp.Result) } // UserDetail sets or gets single detail value, or gets all details for requested site.