fluid-telegram/internal/adaptercfg/adaptercfg_test.go
tegwick b09a5e21d4 Address channels in Bot API form and add a founder-run send script
The provisioner records the MTProto channel id; the Bot API needs -100<id>.
adapter-config now converts it, so the test channel resolves to
-1004427430639. scripts/send-post.sh starts a short-lived adapter with the
bot token injected from OpenBao (never printed) and sends one reviewed post.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5457@bnt-lap001
Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012
2026-10-08 09:36:03 +02:00

129 lines
3.9 KiB
Go

package adaptercfg
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/tegwick/fluid-telegram/internal/secrets"
"github.com/tegwick/fluid-telegram/internal/spec"
"github.com/tegwick/fluid-telegram/internal/state"
)
func provisioned() *state.Resolved {
now := time.Now()
return &state.Resolved{
Campaign: "hall-of-helix",
Bot: state.Bot{Username: "HelixForgeBot", ID: 42},
Channels: map[string]state.Channel{
spec.Test: {ChatID: -1001, AdminRights: []string{spec.PostMessages}, TestPublicationAt: &now},
spec.Live: {ChatID: -2002, Username: "hallofhelix", AdminRights: []string{spec.PostMessages}},
},
}
}
func TestFromResolvedPicksOneChannel(t *testing.T) {
cfg, err := FromResolved(provisioned(), spec.Test, "bao:platform/x/bot-token")
if err != nil {
t.Fatal(err)
}
if cfg.ChatID != -1001 || cfg.Channel != spec.Test {
t.Fatalf("got %+v", cfg)
}
cfg, err = FromResolved(provisioned(), spec.Live, "bao:platform/x/bot-token")
if err != nil {
t.Fatal(err)
}
if cfg.ChatID != -2002 {
t.Fatalf("public chat id = %d", cfg.ChatID)
}
}
func TestFromResolvedRefusesUnprovisioned(t *testing.T) {
if _, err := FromResolved(&state.Resolved{}, spec.Test, "ref"); err == nil {
t.Fatal("accepted an empty state")
}
rs := provisioned()
delete(rs.Channels, spec.Live)
rs.Channels[spec.Test] = state.Channel{ChatID: -1001, AdminRights: []string{spec.PostMessages}}
if _, err := FromResolved(rs, spec.Live, "ref"); err == nil {
t.Fatal("accepted a public channel that has not been provisioned")
}
}
func TestEnvFileHasNoToken(t *testing.T) {
cfg, _ := FromResolved(provisioned(), spec.Test, "bao:platform/x/bot-token")
out := cfg.EnvFile()
for _, line := range strings.Split(out, "\n") {
if strings.HasPrefix(line, "TELEGRAM_BOT_TOKEN=") {
t.Fatal("env file emitted a token value")
}
}
if !strings.Contains(out, "TELEGRAM_CHANNEL_ID=-1001") {
t.Fatalf("missing chat id:\n%s", out)
}
if !strings.Contains(out, "TELEGRAM_BOT_TOKEN_REF=bao:platform/x/bot-token") {
t.Fatalf("missing token ref:\n%s", out)
}
if strings.Contains(out, "operator-session") {
t.Fatal("adapter config mentioned the operator session")
}
}
func TestLoadTokenReadsOnlyTheBotToken(t *testing.T) {
var requested []string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requested = append(requested, r.URL.Path)
if strings.Contains(r.URL.Path, secrets.KeyOperatorSession) {
t.Errorf("adapter requested the operator session: %s", r.URL.Path)
w.WriteHeader(http.StatusForbidden)
return
}
if !strings.HasSuffix(r.URL.Path, "/"+secrets.KeyBotToken) {
t.Errorf("unexpected path %s", r.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(map[string]any{
"data": map[string]any{"data": map[string]string{"token": "123:abc"}},
})
}))
t.Cleanup(srv.Close)
t.Setenv("BAO_ADDR", srv.URL)
t.Setenv("BAO_TOKEN", "test-token")
store, err := secrets.NewFromEnv("hall-of-helix")
if err != nil {
t.Fatal(err)
}
got, err := LoadToken(context.Background(), store)
if err != nil {
t.Fatal(err)
}
if got != "123:abc" {
t.Fatalf("token = %q", got)
}
for _, p := range requested {
if strings.Contains(p, secrets.KeyOperatorSession) || strings.Contains(p, secrets.KeyOperatorApp) {
t.Fatalf("adapter store was asked for %s", p)
}
}
}
func TestBotAPIChatIDPrefixesChannelIDs(t *testing.T) {
if got := BotAPIChatID(4427430639); got != -1004427430639 {
t.Fatalf("BotAPIChatID(4427430639) = %d", got)
}
if got := BotAPIChatID(-1001); got != -1001 {
t.Fatalf("an id already in Bot API form changed: %d", got)
}
rs := provisioned()
rs.Channels[spec.Test] = state.Channel{ChatID: 4427430639, AdminRights: []string{spec.PostMessages}}
cfg, err := FromResolved(rs, spec.Test, "ref")
if err != nil || cfg.ChatID != -1004427430639 {
t.Fatalf("FromResolved chat id = %d, err %v", cfg.ChatID, err)
}
}