mirror of
https://github.com/tiennm99/openai-status-bot.git
synced 2026-07-14 09:05:43 +00:00
128 lines
4.4 KiB
Go
128 lines
4.4 KiB
Go
package telegram
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
tgbot "github.com/go-telegram/bot"
|
|
tgmodels "github.com/go-telegram/bot/models"
|
|
)
|
|
|
|
type fakeFrameworkSender struct {
|
|
params *tgbot.SendMessageParams
|
|
err error
|
|
}
|
|
|
|
func (f *fakeFrameworkSender) SendMessage(_ context.Context, params *tgbot.SendMessageParams) (*tgmodels.Message, error) {
|
|
f.params = params
|
|
return &tgmodels.Message{}, f.err
|
|
}
|
|
|
|
func TestSendTextUsesHTMLAndDisablesPreview(t *testing.T) {
|
|
framework := &fakeFrameworkSender{}
|
|
sender := NewSender(framework, "token", 0)
|
|
|
|
if err := sender.SendText(context.Background(), 123, nil, "<b>hello</b>"); err != nil {
|
|
t.Fatalf("SendText returned error: %v", err)
|
|
}
|
|
if framework.params == nil {
|
|
t.Fatal("SendMessage params were not captured")
|
|
}
|
|
if framework.params.ChatID != int64(123) {
|
|
t.Fatalf("ChatID = %v, want 123", framework.params.ChatID)
|
|
}
|
|
if framework.params.ParseMode != tgmodels.ParseModeHTML {
|
|
t.Fatalf("ParseMode = %v, want HTML", framework.params.ParseMode)
|
|
}
|
|
if framework.params.LinkPreviewOptions == nil || framework.params.LinkPreviewOptions.IsDisabled == nil || !*framework.params.LinkPreviewOptions.IsDisabled {
|
|
t.Fatalf("LinkPreviewOptions = %+v, want disabled preview", framework.params.LinkPreviewOptions)
|
|
}
|
|
}
|
|
|
|
func TestSendTextPassesThreadID(t *testing.T) {
|
|
framework := &fakeFrameworkSender{}
|
|
sender := NewSender(framework, "token", 0)
|
|
threadID := 42
|
|
|
|
if err := sender.SendText(context.Background(), 123, &threadID, "hello"); err != nil {
|
|
t.Fatalf("SendText returned error: %v", err)
|
|
}
|
|
if framework.params.MessageThreadID != threadID {
|
|
t.Fatalf("MessageThreadID = %d, want %d", framework.params.MessageThreadID, threadID)
|
|
}
|
|
}
|
|
|
|
func TestIsTerminalSendError(t *testing.T) {
|
|
terminal := &APIError{StatusCode: http.StatusOK, ErrorCode: http.StatusForbidden, Description: "Forbidden: bot was blocked by the user"}
|
|
if !IsTerminalSendError(terminal) {
|
|
t.Fatal("403 blocked should be terminal")
|
|
}
|
|
chatNotFound := &APIError{StatusCode: http.StatusOK, ErrorCode: http.StatusBadRequest, Description: "Bad Request: chat not found"}
|
|
if !IsTerminalSendError(chatNotFound) {
|
|
t.Fatal("chat not found should be terminal")
|
|
}
|
|
parseError := &APIError{StatusCode: http.StatusOK, ErrorCode: http.StatusBadRequest, Description: "Bad Request: can't parse entities"}
|
|
if IsTerminalSendError(parseError) {
|
|
t.Fatal("parse errors should not remove subscribers")
|
|
}
|
|
legacyForbidden := &APIError{StatusCode: http.StatusForbidden, Description: "Forbidden"}
|
|
if !IsTerminalSendError(legacyForbidden) {
|
|
t.Fatal("status-code-only 403 should remain terminal")
|
|
}
|
|
}
|
|
|
|
func TestSendTextMapsFrameworkForbiddenToTerminalAPIError(t *testing.T) {
|
|
framework := &fakeFrameworkSender{err: fmt.Errorf("%w, Forbidden: bot was kicked", tgbot.ErrorForbidden)}
|
|
sender := NewSender(framework, "token", 0)
|
|
|
|
err := sender.SendText(context.Background(), 123, nil, "hello")
|
|
var apiErr *APIError
|
|
if !errors.As(err, &apiErr) {
|
|
t.Fatalf("SendText error = %v, want APIError", err)
|
|
}
|
|
if apiErr.ErrorCode != http.StatusForbidden {
|
|
t.Fatalf("ErrorCode = %d, want %d", apiErr.ErrorCode, http.StatusForbidden)
|
|
}
|
|
if !IsTerminalSendError(err) {
|
|
t.Fatal("framework forbidden error should be terminal")
|
|
}
|
|
}
|
|
|
|
func TestSendTextMapsFrameworkBadRequestWithoutRemovingSubscriber(t *testing.T) {
|
|
framework := &fakeFrameworkSender{err: fmt.Errorf("%w, Bad Request: can't parse entities", tgbot.ErrorBadRequest)}
|
|
sender := NewSender(framework, "token", 0)
|
|
|
|
err := sender.SendText(context.Background(), 123, nil, "hello")
|
|
var apiErr *APIError
|
|
if !errors.As(err, &apiErr) {
|
|
t.Fatalf("SendText error = %v, want APIError", err)
|
|
}
|
|
if apiErr.ErrorCode != http.StatusBadRequest {
|
|
t.Fatalf("ErrorCode = %d, want %d", apiErr.ErrorCode, http.StatusBadRequest)
|
|
}
|
|
if IsTerminalSendError(err) {
|
|
t.Fatal("parse errors should not remove subscribers")
|
|
}
|
|
}
|
|
|
|
func TestTransportErrorRedactsBotToken(t *testing.T) {
|
|
const token = "123456:super-secret-token"
|
|
framework := &fakeFrameworkSender{err: errors.New("Post https://api.telegram.org/bot" + token + "/sendMessage: dial tcp")}
|
|
sender := NewSender(framework, token, 0)
|
|
|
|
err := sender.SendText(context.Background(), 123, nil, "hello")
|
|
if err == nil {
|
|
t.Fatal("expected transport error, got nil")
|
|
}
|
|
if strings.Contains(err.Error(), token) {
|
|
t.Fatalf("error leaked bot token: %v", err)
|
|
}
|
|
if !strings.Contains(err.Error(), "<redacted>") {
|
|
t.Fatalf("error missing redaction placeholder: %v", err)
|
|
}
|
|
}
|