diff --git a/backend/app/telegram/telegram_test.go b/backend/app/telegram/telegram_test.go index 3fd1ae6..93eb581 100644 --- a/backend/app/telegram/telegram_test.go +++ b/backend/app/telegram/telegram_test.go @@ -34,6 +34,7 @@ func init() { ) setupBot() + setupCommandHandlers() } func getTestBot() *telego.Bot { @@ -42,7 +43,7 @@ func getTestBot() *telego.Bot { func setupBot() { BOT = &Bot{ - Name: "test", + Name: "testbot", Bot: getTestBot(), } } @@ -65,143 +66,6 @@ func getSendMessageFuncAssertion(t *testing.T, expectedRegex string, expectedCha } } -// func HandleMessage(bot *telego.Bot, message telego.Message) { -// chatID := util.GetChatID(&message) -// chatIDString := util.GetChatIDString(&message) -// isPrivate := message.Chat.Type == "private" -// _, ctx, cancelContext, err := lib.SetupUserAndContext(chatIDString, "telegram", chatIDString) -// if err != nil { -// if err == lib.ErrUserBanned { -// log.Infof("User %s is banned", chatIDString) -// return -// } - -// log.Errorf("Error setting up user and context: %v", err) -// return -// } - -// // process commands -// if message.Voice == nil && message.Audio == nil && message.Video == nil && message.VideoNote == nil && message.Document == nil && message.Photo == nil && (message.Text == string(EmptyCommand) || strings.HasPrefix(message.Text, "/")) { -// if !isPrivate && !strings.Contains(message.Text, "@"+BOT.Name) { -// log.Infof("Ignoring public command w/o @mention in channel: %s", chatIDString) -// return -// } -// AllCommandHandlers.handleCommand(ctx, BOT, &message) -// return -// } - -// mode, params := lib.GetMode(chatIDString) -// log.Infof("chat %s, mode: %s, params: %s", chatIDString, mode, params) -// ctx = context.WithValue(ctx, models.ParamsContext{}, params) -// // while in channels, only react to -// // 1. @mentions -// // 2. audio messages in /transcribe mode -// // 3. /grammar fixes -// if !isPrivate && mode != lib.Transcribe && mode != lib.Grammar && !strings.Contains(message.Text, "@"+BOT.Name) { -// log.Infof("Ignoring public message w/o @mention and not in transcribe or grammar mode in channel: %s", chatIDString) -// return -// } - -// if message.Video != nil && strings.HasPrefix(message.Caption, string(SYSTEMSetOnboardingVideoCommand)) { -// log.Infof("System command received: %+v", message) // audit -// message.Text = string(SYSTEMSetOnboardingVideoCommand) -// AllCommandHandlers.handleCommand(ctx, BOT, &message) -// return -// } - -// // user usage exceeded monthly limit, send message and return -// ok := lib.ValidateUserUsage(ctx) -// if !ok { -// notification := "Your monthly usage limit has been exceeded. Check /status and /upgrade your subscription to continue using the bot. The limits are reset on the 1st of every month." -// notification = lib.AddBotSuffixToGroupCommands(ctx, notification) -// bot.SendMessage(tu.Message(chatID, notification)) -// config.CONFIG.DataDogClient.Incr("telegram.usage_exceeded", []string{"client:telegram", "channel_type:" + message.Chat.Type}, 1) -// return -// } - -// voiceTranscriptionText := "" -// // if the message is voice/audio/video message, process it to upload to WhisperAI API and get the transcription -// if message.Voice != nil || message.Audio != nil || message.Video != nil || message.VideoNote != nil || message.Document != nil { -// voice_type := "voice" -// switch { -// case message.Audio != nil: -// voice_type = "audio" -// case message.Video != nil: -// voice_type = "video" -// case message.VideoNote != nil: -// voice_type = "note" -// case message.Document != nil: -// voice_type = "document" -// } -// config.CONFIG.DataDogClient.Incr("telegram.voice_message_received", []string{"type:" + voice_type, "channel_type:" + message.Chat.Type}, 1) - -// // send typing action to show that bot is working -// if mode != lib.VoiceGPT { -// sendTypingAction(bot, chatID) -// } else { -// sendAudioAction(bot, chatID) -// } -// voiceTranscriptionText = getVoiceTranscript(ctx, bot, message) - -// if mode != lib.Transcribe { -// // combine message text with transcription -// if voiceTranscriptionText != "" { -// message.Text = message.Text + "\n" + voiceTranscriptionText -// } - -// // process commands again if it was a voice command -// if message.Text == string(EmptyCommand) || strings.HasPrefix(message.Text, "/") { -// AllCommandHandlers.handleCommand(ctx, BOT, &message) -// return -// } -// } -// } - -// if mode == lib.Transcribe { -// ChunkSendMessage(bot, chatID, voiceTranscriptionText) -// if isPrivate && message.Text != "" { -// bot.SendMessage(tu.Message(chatID, "The bot is in /transcribe mode. Please send a voice/audio/video message to transcribe or change to another mode (/status).")) -// } -// return -// } - -// if mode != lib.VoiceGPT && !(mode == lib.Grammar && !isPrivate) && voiceTranscriptionText != "" { -// ChunkSendMessage(bot, chatID, "🗣:\n"+voiceTranscriptionText) -// } - -// if message.Text != "" { -// config.CONFIG.DataDogClient.Incr("telegram.text_message_received", []string{"channel_type:" + message.Chat.Type}, 1) -// } else { -// log.Infof("Ignoring empty message in chat: %s", chatIDString) -// return -// } - -// if message.Photo != nil { -// config.CONFIG.DataDogClient.Incr("telegram.photo_message_received", []string{"channel_type:" + message.Chat.Type}, 1) -// } - -// var seedData []models.Message -// var userMessagePrimer string -// seedData, userMessagePrimer = lib.GetSeedDataAndPrimer(mode) - -// log.Debugf("Received message: %d, in chat: %d, initiating request to OpenAI", message.MessageID, chatID.ID) -// engineModel := redis.GetChatEngine(chatIDString) - -// // send action to show that bot is working -// if mode != lib.VoiceGPT { -// sendTypingAction(bot, chatID) -// } else { -// sendAudioAction(bot, chatID) -// } -// if mode == lib.ChatGPT || mode == lib.VoiceGPT { -// go ProcessThreadedStreamingMessage(ctx, bot, &message, mode, engineModel, cancelContext) -// } else if mode == lib.Summarize || (mode == lib.Grammar && isPrivate) { -// go ProcessChatCompleteStreamingMessage(ctx, bot, &message, seedData, userMessagePrimer, mode, engineModel, cancelContext) -// } else { -// go ProcessChatCompleteNonStreamingMessage(ctx, bot, &message, seedData, userMessagePrimer, mode, engineModel) -// } -// } - func TestHandleEmptyPublicMessage(t *testing.T) { message := telego.Message{ Chat: telego.Chat{ @@ -209,6 +73,7 @@ func TestHandleEmptyPublicMessage(t *testing.T) { }, } + // act HandleMessage(BOT.Bot, message) } @@ -220,6 +85,92 @@ func TestHandleEmptyPrivateMessage(t *testing.T) { }, } + sendMessagePatch, err := mpatch.PatchInstanceMethodByName( + reflect.TypeOf(BOT.Bot), + "SendMessage", + getSendMessageFuncAssertion(t, "There is no message provided to correct or comment on", 123), + ) + if err != nil { + t.Fatal(err) + } + defer sendMessagePatch.Unpatch() + + // act + HandleMessage(BOT.Bot, message) +} + +func TestHandlePrivateStartCommandMessage(t *testing.T) { + // arrange + message := telego.Message{ + Chat: telego.Chat{ + ID: 123, + Type: "private", + }, + Text: "/start", + } + + sendMessagePatch, err := mpatch.PatchInstanceMethodByName( + reflect.TypeOf(BOT.Bot), + "SendMessage", + getSendMessageFuncAssertion(t, "Hi, I'm a bot powered by OpenAI!", 123), + ) + if err != nil { + t.Fatal(err) + } + defer sendMessagePatch.Unpatch() + + // act + HandleMessage(BOT.Bot, message) +} + +func TestHandlePublicStartCommandMessage(t *testing.T) { + // arrange + message := telego.Message{ + Chat: telego.Chat{ + ID: 123, + Type: "supergroup", + }, + Text: "/start@testbot", + } + + sendMessagePatch, err := mpatch.PatchInstanceMethodByName( + reflect.TypeOf(BOT.Bot), + "SendMessage", + getSendMessageFuncAssertion(t, "Hi, I'm a bot powered by OpenAI!", 123), + ) + if err != nil { + t.Fatal(err) + } + defer sendMessagePatch.Unpatch() + + // act + HandleMessage(BOT.Bot, message) +} + +func TestHandlePublicStartCommandNoMentionMessage(t *testing.T) { + // arrange + message := telego.Message{ + Chat: telego.Chat{ + ID: 123, + Type: "supergroup", + }, + Text: "/start", + } + + // act + HandleMessage(BOT.Bot, message) +} + +func TestHandlePublicUnknownCommandMessage(t *testing.T) { + // arrange + message := telego.Message{ + Chat: telego.Chat{ + ID: 123, + Type: "supergroup", + }, + Text: "/destroy@testbot", + } + sendMessagePatch, err := mpatch.PatchInstanceMethodByName( reflect.TypeOf(BOT.Bot), "SendMessage", @@ -230,5 +181,6 @@ func TestHandleEmptyPrivateMessage(t *testing.T) { } defer sendMessagePatch.Unpatch() + // act HandleMessage(BOT.Bot, message) }