/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/chat/botcommands_test.go
219 строк
7 KB
chrisnojima-zoom
Version 670 - clean2 (#29122)
08 июн 2026, 19:31
Не верифицирован
08 июн 2026, 19:31
1943197
Код
Авторство
О чём код?
package chat import ( "errors" "testing" "time" "github.com/keybase/client/go/chat/types" "github.com/keybase/client/go/chat/utils" "github.com/keybase/client/go/libkb" "github.com/keybase/client/go/protocol/chat1" "github.com/keybase/client/go/protocol/gregor1" "github.com/keybase/client/go/protocol/keybase1" "github.com/stretchr/testify/require" ) type dummyUIRouter struct { libkb.UIRouter } func (d dummyUIRouter) GetChatUI() (libkb.ChatUI, error) { return nil, nil } func (d dummyUIRouter) Shutdown() {} func TestBotCommandManager(t *testing.T) { useRemoteMock = false defer func() { useRemoteMock = true }() ctc := makeChatTestContext(t, "TestBotCommandManager", 3) defer ctc.cleanup() timeout := 20 * time.Second users := ctc.users() listener := newServerChatListener() ctc.as(t, users[0]).h.G().NotifyRouter.AddListener(listener) tc := ctc.world.Tcs[users[0].Username] tc.G.UIRouter = dummyUIRouter{} tc1 := ctc.world.Tcs[users[1].Username] tc1.G.UIRouter = dummyUIRouter{} tc2 := ctc.world.Tcs[users[2].Username] tc2.G.UIRouter = dummyUIRouter{} ctx := ctc.as(t, users[0]).startCtx ctx1 := ctc.as(t, users[1]).startCtx ctx2 := ctc.as(t, users[2]).startCtx uid := gregor1.UID(users[0].GetUID().ToBytes()) botua := users[2] t.Logf("uid: %s", uid) listener0 := newServerChatListener() ctc.as(t, users[0]).h.G().NotifyRouter.AddListener(listener0) impConv := mustCreateConversationForTest(t, ctc, users[0], chat1.TopicType_CHAT, chat1.ConversationMembersType_IMPTEAMNATIVE) impConv1 := mustCreateConversationForTest(t, ctc, users[1], chat1.TopicType_CHAT, chat1.ConversationMembersType_IMPTEAMNATIVE, users[0]) t.Logf("impconv: %s", impConv.Id) t.Logf("impconv1: %s", impConv1.Id) teamConv := mustCreateConversationForTest(t, ctc, users[0], chat1.TopicType_CHAT, chat1.ConversationMembersType_TEAM) t.Logf("teamconv: %x", teamConv.Id.DbShortForm()) // test public alias := "MIKE BOT" commands := []chat1.AdvertiseCommandsParam{ { Typ: chat1.BotCommandsAdvertisementTyp_PUBLIC, Commands: []chat1.UserBotCommandInput{ { Name: "status", Description: "get status", Usage: "just type it", }, }, }, } require.NoError(t, tc.Context().BotCommandManager.Advertise(ctx, &alias, commands)) cmds, _, err := tc.Context().BotCommandManager.ListCommands(ctx, impConv.Id) require.NoError(t, err) require.Zero(t, len(cmds)) errCh, err := tc.Context().BotCommandManager.UpdateCommands(ctx, impConv.Id, nil) require.NoError(t, err) errCh1, err := tc1.Context().BotCommandManager.UpdateCommands(ctx1, impConv1.Id, nil) require.NoError(t, err) readErrCh := func(errCh chan error) error { select { case err := <-errCh: return err case <-time.After(timeout): return errors.New("timeout") } } select { case convID := <-listener0.convUpdate: require.Equal(t, impConv.Id, convID) case <-time.After(timeout): require.Fail(t, "no stale") } impConvLocal, err := utils.GetVerifiedConv(ctx, tc.Context(), uid, impConv.Id, types.InboxSourceDataSourceAll) require.NoError(t, err) typ, err := impConvLocal.BotCommands.Typ() require.NoError(t, err) require.Equal(t, chat1.ConversationCommandGroupsTyp_CUSTOM, typ) require.Equal(t, 1, len(impConvLocal.BotCommands.Custom().Commands)) require.Equal(t, "status", impConvLocal.BotCommands.Custom().Commands[0].Name) require.NoError(t, readErrCh(errCh)) cmds, _, err = tc.Context().BotCommandManager.ListCommands(ctx, impConv.Id) require.NoError(t, err) require.Equal(t, 1, len(cmds)) require.Equal(t, "status", cmds[0].Name) // make sure the cmds are cached for range 5 { errCh, err = tc.Context().BotCommandManager.UpdateCommands(ctx, impConv.Id, nil) require.NoError(t, err) require.NoError(t, readErrCh(errCh)) } select { case <-listener0.convUpdate: require.Fail(t, "commands not cached") default: } require.NoError(t, readErrCh(errCh1)) cmds, _, err = tc1.Context().BotCommandManager.ListCommands(ctx1, impConv1.Id) require.NoError(t, err) require.Equal(t, 1, len(cmds)) require.Equal(t, "status", cmds[0].Name) // test team teamID, err := keybase1.TeamIDFromString(teamConv.Triple.Tlfid.String()) require.NoError(t, err) pollForSeqno := func(expectedSeqno keybase1.Seqno) { found := false for !found { select { case teamChange := <-listener.teamChangedByID: found = teamChange.TeamID == teamID && teamChange.LatestSeqno == expectedSeqno case <-time.After(20 * time.Second): require.Fail(t, "no event received") } } } commands = append(commands, chat1.AdvertiseCommandsParam{ Typ: chat1.BotCommandsAdvertisementTyp_TLFID_CONVS, Commands: []chat1.UserBotCommandInput{{ Name: "teamconvonly", }}, TeamName: &teamConv.TlfName, }, chat1.AdvertiseCommandsParam{ Typ: chat1.BotCommandsAdvertisementTyp_TLFID_MEMBERS, Commands: []chat1.UserBotCommandInput{{ Name: "teammembsonly", }}, TeamName: &teamConv.TlfName, }, chat1.AdvertiseCommandsParam{ Typ: chat1.BotCommandsAdvertisementTyp_CONV, Commands: []chat1.UserBotCommandInput{{ Name: "conv", }}, ConvID: &teamConv.Id, }) require.NoError(t, tc.Context().BotCommandManager.Advertise(ctx, &alias, commands)) errCh, err = tc.Context().BotCommandManager.UpdateCommands(ctx, impConv.Id, nil) require.NoError(t, err) require.NoError(t, readErrCh(errCh)) errChT, err := tc.Context().BotCommandManager.UpdateCommands(ctx, teamConv.Id, nil) require.NoError(t, err) require.NoError(t, readErrCh(errChT)) errCh1, err = tc1.Context().BotCommandManager.UpdateCommands(ctx, impConv1.Id, nil) require.NoError(t, err) require.NoError(t, readErrCh(errCh1)) cmds, _, err = tc.Context().BotCommandManager.ListCommands(ctx, impConv.Id) require.NoError(t, err) require.Equal(t, 2, len(cmds)) cmds, _, err = tc.Context().BotCommandManager.ListCommands(ctx, teamConv.Id) require.NoError(t, err) require.Equal(t, 4, len(cmds)) cmds, _, err = tc1.Context().BotCommandManager.ListCommands(ctx1, impConv1.Id) require.NoError(t, err) require.Equal(t, 1, len(cmds)) err = ctc.as(t, users[0]).chatLocalHandler().AddBotMember(ctx, chat1.AddBotMemberArg{ ConvID: teamConv.Id, Username: botua.Username, Role: keybase1.TeamRole_RESTRICTEDBOT, BotSettings: &keybase1.TeamBotSettings{Cmds: true}, }) require.NoError(t, err) require.NoError(t, tc2.Context().BotCommandManager.Advertise(ctx2, &alias, commands)) pollForSeqno(3) errChT, err = tc.Context().BotCommandManager.UpdateCommands(ctx, teamConv.Id, nil) require.NoError(t, err) require.NoError(t, readErrCh(errChT)) cmds, _, err = tc.Context().BotCommandManager.ListCommands(ctx, teamConv.Id) require.NoError(t, err) require.Equal(t, 8, len(cmds)) // impteams can't advertise on team types commands = append(commands, chat1.AdvertiseCommandsParam{ Typ: chat1.BotCommandsAdvertisementTyp_TLFID_CONVS, Commands: []chat1.UserBotCommandInput{{ Name: "teamconvonly_implicit", }}, TeamName: &impConv.TlfName, }) require.Error(t, tc.Context().BotCommandManager.Advertise(ctx, &alias, commands)) }