mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
156 lines
4.0 KiB
Go
156 lines
4.0 KiB
Go
package channel
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
type fakeWebhookAdapter struct {
|
|
channelType ChannelType
|
|
calls []struct {
|
|
cfg ChannelConfig
|
|
method string
|
|
}
|
|
}
|
|
|
|
func (a *fakeWebhookAdapter) Type() ChannelType { return a.channelType }
|
|
|
|
func (a *fakeWebhookAdapter) Descriptor() Descriptor {
|
|
return Descriptor{
|
|
Type: a.channelType,
|
|
DisplayName: strings.ToUpper(a.channelType.String()),
|
|
}
|
|
}
|
|
|
|
func (a *fakeWebhookAdapter) HandleWebhook(ctx context.Context, cfg ChannelConfig, handler InboundHandler, r *http.Request, w http.ResponseWriter) error {
|
|
a.calls = append(a.calls, struct {
|
|
cfg ChannelConfig
|
|
method string
|
|
}{cfg: cfg, method: r.Method})
|
|
if handler != nil {
|
|
if err := handler(ctx, cfg, InboundMessage{
|
|
Channel: cfg.ChannelType,
|
|
BotID: cfg.BotID,
|
|
Message: Message{Format: MessageFormatPlain, Text: "hello"},
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
return nil
|
|
}
|
|
|
|
type fakeWebhookStore struct {
|
|
configs []ChannelConfig
|
|
err error
|
|
}
|
|
|
|
func (s *fakeWebhookStore) ListConfigsByType(_ context.Context, channelType ChannelType) ([]ChannelConfig, error) {
|
|
if s.err != nil {
|
|
return nil, s.err
|
|
}
|
|
items := make([]ChannelConfig, 0, len(s.configs))
|
|
for _, item := range s.configs {
|
|
if item.ChannelType == channelType {
|
|
items = append(items, item)
|
|
}
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
type fakeWebhookManager struct {
|
|
registry *Registry
|
|
calls []struct {
|
|
cfg ChannelConfig
|
|
msg InboundMessage
|
|
}
|
|
}
|
|
|
|
func (m *fakeWebhookManager) HandleInbound(_ context.Context, cfg ChannelConfig, msg InboundMessage) error {
|
|
m.calls = append(m.calls, struct {
|
|
cfg ChannelConfig
|
|
msg InboundMessage
|
|
}{cfg: cfg, msg: msg})
|
|
return nil
|
|
}
|
|
|
|
func (m *fakeWebhookManager) Registry() *Registry { return m.registry }
|
|
|
|
func TestGenericWebhookHandlerDispatchesToAdapter(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry := NewRegistry()
|
|
adapter := &fakeWebhookAdapter{channelType: ChannelType("testhook")}
|
|
registry.MustRegister(adapter)
|
|
|
|
store := &fakeWebhookStore{
|
|
configs: []ChannelConfig{{
|
|
ID: "cfg-1",
|
|
BotID: "bot-1",
|
|
ChannelType: adapter.channelType,
|
|
}},
|
|
}
|
|
manager := &fakeWebhookManager{registry: registry}
|
|
h := NewWebhookServerHandler(nil, (*Store)(nil), (*Manager)(nil))
|
|
h.store = store
|
|
h.manager = manager
|
|
h.registry = registry
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/channels/testhook/webhook/cfg-1", strings.NewReader(`{}`))
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.SetParamNames("platform", "config_id")
|
|
c.SetParamValues("testhook", "cfg-1")
|
|
|
|
if err := h.Handle(c); err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if rec.Code != http.StatusNoContent {
|
|
t.Fatalf("unexpected status code: %d", rec.Code)
|
|
}
|
|
if len(adapter.calls) != 1 {
|
|
t.Fatalf("expected adapter to be called once, got %d", len(adapter.calls))
|
|
}
|
|
if len(manager.calls) != 1 {
|
|
t.Fatalf("expected inbound manager to be called once, got %d", len(manager.calls))
|
|
}
|
|
}
|
|
|
|
func TestGenericWebhookHandlerRejectsUnknownConfig(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry := NewRegistry()
|
|
registry.MustRegister(&fakeWebhookAdapter{channelType: ChannelType("testhook")})
|
|
manager := &fakeWebhookManager{registry: registry}
|
|
h := NewWebhookServerHandler(nil, (*Store)(nil), (*Manager)(nil))
|
|
h.store = &fakeWebhookStore{}
|
|
h.manager = manager
|
|
h.registry = registry
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequestWithContext(context.Background(), http.MethodPost, "/channels/testhook/webhook/missing", strings.NewReader(`{}`))
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
c.SetParamNames("platform", "config_id")
|
|
c.SetParamValues("testhook", "missing")
|
|
|
|
err := h.Handle(c)
|
|
if err == nil {
|
|
t.Fatal("expected not found error")
|
|
}
|
|
var httpErr *echo.HTTPError
|
|
if !errors.As(err, &httpErr) {
|
|
t.Fatalf("expected HTTPError, got %T", err)
|
|
}
|
|
if httpErr.Code != http.StatusNotFound {
|
|
t.Fatalf("unexpected status code: %d", httpErr.Code)
|
|
}
|
|
}
|