package provider import ( "context" "io" "net/http" "strings" "testing" "time" "github.com/go-resty/resty/v2" "github.com/gochat/gochat/internal/channel" "github.com/gochat/gochat/internal/model" ) func TestTelegramProvider_CreateChannelReturnsWebhookSetupFailure(t *testing.T) { provider := NewTelegramProvider() provider.client = fakeTelegramRestyClient(t, map[string]string{ "/bot123:token/getMe": `{"ok":true,"result":{"id":42,"first_name":"Support Bot","username":"support_bot"}}`, "/bot123:token/deleteWebhook": `{"ok":true,"result":true}`, "/bot123:token/setWebhook": `{"ok":false,"description":"webhook URL is invalid"}`, }) _, err := provider.CreateChannel(context.Background(), 1, channel.ChannelConfig{"bot_token": "123:token"}) if err == nil || !strings.Contains(err.Error(), "telegram webhook setup failed") || !strings.Contains(err.Error(), "webhook URL is invalid") { t.Fatalf("expected webhook setup failure, got %v", err) } } func TestTelegramProvider_OnCreateFlagsReauthorizationOnWebhookFailure(t *testing.T) { provider := NewTelegramProvider() provider.client = fakeTelegramRestyClient(t, map[string]string{ "/bot123:token/deleteWebhook": `{"ok":true,"result":true}`, "/bot123:token/setWebhook": `{"ok":false,"description":"webhook URL is invalid"}`, }) config, err := provider.OnCreate(context.Background(), &model.Inbox{ChannelType: "telegram"}, channel.ChannelConfig{"bot_token": "123:token"}) if err != nil { t.Fatalf("expected OnCreate to keep inbox creation non-fatal, got %v", err) } if config["reauthorization_required"] != true { t.Fatalf("expected reauthorization_required=true, got %#v", config) } if _, ok := config["webhook_url"]; ok { t.Fatalf("expected webhook_url to be omitted on setup failure, got %#v", config["webhook_url"]) } } func TestTelegramProvider_OnCreateStoresWebhookURLOnSuccess(t *testing.T) { t.Setenv("FRONTEND_URL", "https://app.example.test") provider := NewTelegramProvider() provider.client = fakeTelegramRestyClient(t, map[string]string{ "/bot123:token/deleteWebhook": `{"ok":true,"result":true}`, "/bot123:token/setWebhook": `{"ok":true,"result":true}`, }) config, err := provider.OnCreate(context.Background(), &model.Inbox{ChannelType: "telegram"}, channel.ChannelConfig{"bot_token": "123:token"}) if err != nil { t.Fatalf("expected successful OnCreate, got %v", err) } if config["reauthorization_required"] != false { t.Fatalf("expected reauthorization_required=false, got %#v", config) } if config["webhook_url"] != "https://app.example.test/webhooks/telegram/123:token" { t.Fatalf("unexpected webhook_url: %#v", config["webhook_url"]) } } func fakeTelegramRestyClient(t *testing.T, responses map[string]string) *resty.Client { t.Helper() client := resty.New() client.SetTimeout(2 * time.Second) client.SetRetryCount(0) client.SetTransport(roundTripFunc(func(req *http.Request) (*http.Response, error) { body, ok := responses[req.URL.Path] if !ok { t.Fatalf("unexpected telegram API request: %s %s", req.Method, req.URL.Path) } return &http.Response{ StatusCode: http.StatusOK, Header: http.Header{"Content-Type": []string{"application/json"}}, Body: io.NopCloser(strings.NewReader(body)), Request: req, }, nil })) return client } type roundTripFunc func(*http.Request) (*http.Response, error) func (fn roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { return fn(req) }