182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
package webhook
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter"
|
|
)
|
|
|
|
func TestName(t *testing.T) {
|
|
t.Parallel()
|
|
if got := New().Name(); got != "webhook" {
|
|
t.Errorf("Name() = %q, want webhook", got)
|
|
}
|
|
}
|
|
|
|
func TestConfigSnapshot(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := Config{
|
|
EndpointPath: "/cb",
|
|
ChannelID: "ch-1",
|
|
ChannelName: "My Hook",
|
|
Secret: "s3cr3t",
|
|
Methods: []string{http.MethodPost, http.MethodPut},
|
|
}
|
|
got := New(WithConfig(cfg)).Config()
|
|
if got["endpointPath"] != "/cb" {
|
|
t.Errorf("Config() endpointPath = %v, want /cb", got["endpointPath"])
|
|
}
|
|
if got["channelId"] != "ch-1" {
|
|
t.Errorf("Config() channelId = %v, want ch-1", got["channelId"])
|
|
}
|
|
if got["secret"] != "s3cr3t" {
|
|
t.Errorf("Config() secret = %v, want s3cr3t", got["secret"])
|
|
}
|
|
if got["signatureHeader"] != defaultSignatureHeader {
|
|
t.Errorf("Config() signatureHeader = %v, want %s", got["signatureHeader"], defaultSignatureHeader)
|
|
}
|
|
}
|
|
|
|
func TestConnectDisconnectHealthCheck(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := New()
|
|
if a.IsConnected() {
|
|
t.Error("IsConnected() = true before Connect, want false")
|
|
}
|
|
|
|
if err := a.HealthCheck(context.Background()); !errors.Is(err, adapter.ErrNotConnected) {
|
|
t.Errorf("HealthCheck() before connect error = %v, want ErrNotConnected", err)
|
|
}
|
|
|
|
if err := a.Connect(context.Background()); err != nil {
|
|
t.Errorf("Connect() error = %v", err)
|
|
}
|
|
if !a.IsConnected() {
|
|
t.Error("IsConnected() = false after Connect, want true")
|
|
}
|
|
if err := a.HealthCheck(context.Background()); err != nil {
|
|
t.Errorf("HealthCheck() after connect error = %v", err)
|
|
}
|
|
|
|
if err := a.Disconnect(context.Background()); err != nil {
|
|
t.Errorf("Disconnect() error = %v", err)
|
|
}
|
|
if a.IsConnected() {
|
|
t.Error("IsConnected() = true after Disconnect, want false")
|
|
}
|
|
// Idempotent.
|
|
if err := a.Disconnect(context.Background()); err != nil {
|
|
t.Errorf("Disconnect() second call error = %v", err)
|
|
}
|
|
if err := a.Connect(context.Background()); err != nil {
|
|
t.Errorf("Connect() second call error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCapabilitiesProactiveDisabled(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
caps := New().Capabilities()
|
|
if caps.Proactive {
|
|
t.Error("Capabilities().Proactive = true, want false")
|
|
}
|
|
if caps.MaxMessageLength <= 0 {
|
|
t.Errorf("Capabilities().MaxMessageLength = %d, want normalized nonzero", caps.MaxMessageLength)
|
|
}
|
|
if caps.RecommendBurstMax <= 0 {
|
|
t.Errorf("Capabilities().RecommendBurstMax = %d, want normalized nonzero", caps.RecommendBurstMax)
|
|
}
|
|
}
|
|
|
|
func TestListChannelsConfigured(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := New(WithConfig(Config{ChannelID: "ch-1", ChannelName: "Hook"}))
|
|
chans, err := a.ListChannels(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("ListChannels() error = %v", err)
|
|
}
|
|
if len(chans) != 1 {
|
|
t.Fatalf("ListChannels() len = %d, want 1", len(chans))
|
|
}
|
|
if chans[0].ChannelID != "ch-1" || chans[0].ChannelName != "Hook" {
|
|
t.Errorf("ListChannels()[0] = %+v, want {ch-1 Hook}", chans[0])
|
|
}
|
|
}
|
|
|
|
func TestListChannelsEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
chans, err := New().ListChannels(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("ListChannels() error = %v", err)
|
|
}
|
|
if len(chans) != 0 {
|
|
t.Errorf("ListChannels() len = %d, want 0", len(chans))
|
|
}
|
|
}
|
|
|
|
func TestSendProactiveUnsupported(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
err := New().SendProactive(context.Background(), adapter.UnifiedMessage{})
|
|
if !errors.Is(err, adapter.ErrUnsupported) {
|
|
t.Errorf("SendProactive() error = %v, want ErrUnsupported", err)
|
|
}
|
|
}
|
|
|
|
func TestSendMessageUnsupported(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
err := New().SendMessage(context.Background(), adapter.UnifiedResponse{})
|
|
if !errors.Is(err, adapter.ErrUnsupported) {
|
|
t.Errorf("SendMessage() error = %v, want ErrUnsupported", err)
|
|
}
|
|
}
|
|
|
|
func TestSetMessageHandlerAndClear(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := New()
|
|
a.SetMessageHandler(func(context.Context, adapter.UnifiedMessage) {})
|
|
|
|
// A nil handler clears the installed one, so delivery must fail.
|
|
a.SetMessageHandler(nil)
|
|
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhook",
|
|
bytes.NewReader([]byte(`{"content":"hi"}`)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
a.InboundHandler().ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusServiceUnavailable {
|
|
t.Errorf("status = %d, want 503", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestReadMessagesBlocksUntilCancel(t *testing.T) {
|
|
a := New()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // pre-cancel so the loop returns deterministically
|
|
|
|
done := make(chan struct{})
|
|
go func() {
|
|
a.ReadMessages(ctx, func(adapter.UnifiedMessage) {})
|
|
close(done)
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("ReadMessages() did not return on canceled context")
|
|
}
|
|
}
|