Files
gochat/backend/internal/channel/provider/telegram_test.go
T
rogee aeddedf2a3 Reorganize repo: backend/, deploy/, docs/ layout + AGENTS.md
Restructure the monorepo into clear top-level directories:
- backend/: Go module root (cmd, internal, pkg, configs, migrations,
  docs/swagger, scripts, tests, go.mod, Makefile, .air.toml)
- deploy/: Docker (Dockerfile, docker-compose*), quickstart, fluentd
- docs/: project documentation + reports/ (moved from repo root)
- AGENTS.md: new AI coding-agent guide at repo root

Update all references to the new layout:
- Dockerfile: COPY backend/go.mod, COPY backend/ (context = repo root)
- docker-compose files: context ../.., dockerfile deploy/docker/Dockerfile,
  env_file ../../.env, volume mounts ../../backend:/app
- deploy/quickstart/compose.yaml: dockerfile deploy/docker/Dockerfile
- CI: working-directory: backend for go commands, file deploy/docker/Dockerfile,
  coverage path backend/coverage.out, health_check backend/scripts/
- backend/Makefile: docker target uses -f ../deploy/docker/Dockerfile ../
- README: architecture tree, quickstart, config paths updated

Move root stray scripts (rename_models.*, run_m11_tests.sh, verify_build.sh,
gorm_bool_main.go) to backend/scripts/legacy/. All moves via git mv to
preserve history. Build, vet, SQLite tests, and docker compose config verified.
2026-07-07 14:44:12 +08:00

94 lines
3.4 KiB
Go

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)
}