1101 lines
33 KiB
Go
1101 lines
33 KiB
Go
package webhook
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
"gorm.io/datatypes"
|
|
|
|
"github.com/gochat/gochat/internal/channel"
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
func init() {
|
|
gin.SetMode(gin.TestMode)
|
|
}
|
|
|
|
// safeCall_Cov3 wraps a function call in recover to handle panics from nil-service handlers.
|
|
func safeCall_Cov3(t *testing.T, f func()) {
|
|
t.Helper()
|
|
defer func() { _ = recover() }()
|
|
f()
|
|
}
|
|
|
|
// makeGinContext_Cov3 builds a test gin.Context with the given method, path, body, and headers.
|
|
func makeGinContext_Cov3(method, path string, body []byte, headers map[string]string) (*gin.Context, *httptest.ResponseRecorder) {
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
req := httptest.NewRequest(method, path, bytes.NewReader(body))
|
|
for k, v := range headers {
|
|
req.Header.Set(k, v)
|
|
}
|
|
c.Request = req
|
|
c.Params = gin.Params{}
|
|
return c, w
|
|
}
|
|
|
|
// ============================================================
|
|
// Facebook Webhook — HandleFacebookVerification, HandleFacebookWebhook, HandleInstagramVerification, HandleInstagramWebhook
|
|
// ============================================================
|
|
|
|
func TestHandleFacebookVerification_NilHandler_Cov3(t *testing.T) {
|
|
var h *FacebookWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("GET", "/webhooks/facebook/123?page_id=fbpage", nil, nil)
|
|
h.HandleFacebookVerification(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleFacebookVerification_MissingInbox_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/facebook/123?page_id=fbpage", nil, nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleFacebookVerification(c)
|
|
})
|
|
assert.True(t, w.Code == http.StatusNotFound || w.Code == http.StatusOK)
|
|
}
|
|
|
|
func TestHandleFacebookWebhook_NilHandler_Cov3(t *testing.T) {
|
|
var h *FacebookWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/facebook/123?page_id=fbpage", []byte(`{}`), nil)
|
|
h.HandleFacebookWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleFacebookWebhook_ReadBodyErr_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/facebook/123?page_id=fbpage", []byte(`{}`), nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleFacebookWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleFacebookWebhook_InboxLookupFail_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/facebook/123?page_id=fbpage", []byte(`{"object":"page"}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleFacebookWebhook(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestHandleInstagramVerification_NilHandler_Cov3(t *testing.T) {
|
|
var h *FacebookWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("GET", "/webhooks/instagram?hub.verify_token=tok&hub.challenge=chal", nil, nil)
|
|
h.HandleInstagramVerification(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleInstagramVerification_EmptyToken_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/instagram?hub.verify_token=&hub.challenge=chal", nil, nil)
|
|
h.HandleInstagramVerification(c)
|
|
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
|
}
|
|
|
|
func TestHandleInstagramVerification_WrongToken_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/instagram?hub.verify_token=wrong&hub.challenge=chal", nil, nil)
|
|
h.HandleInstagramVerification(c)
|
|
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
|
}
|
|
|
|
func TestHandleInstagramWebhook_NilHandler_Cov3(t *testing.T) {
|
|
var h *FacebookWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/instagram", []byte(`{}`), nil)
|
|
h.HandleInstagramWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleInstagramWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/instagram", []byte(`not json`), nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleInstagramWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestHandleInstagramWebhook_EmptyEvents_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/instagram", []byte(`{"object":"instagram","entry":[]}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleInstagramWebhook(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestHandleInstagramWebhook_NonInstagramObject_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/instagram", []byte(`{"object":"page","entry":[]}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleInstagramWebhook(c)
|
|
})
|
|
// The webhookParser will try to parse this; it should either be ok or unprocessable
|
|
_ = w
|
|
}
|
|
|
|
// ============================================================
|
|
// Facebook helpers: lookupInbox, lookupFacebookInbox, lookupInstagramInboxForEvent, validInstagramVerifyToken,
|
|
// verifyInstagramSignature, instagramAppSecrets, processInstagramEvent, persistFacebookReceipt
|
|
// ============================================================
|
|
|
|
func TestFB_lookupInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInbox(1)
|
|
})
|
|
}
|
|
|
|
func TestFB_lookupFacebookInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupFacebookInbox("page123", 0)
|
|
})
|
|
}
|
|
|
|
func TestFB_lookupFacebookInbox_WithInboxID_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupFacebookInbox("page123", 999)
|
|
})
|
|
}
|
|
|
|
func TestFB_lookupInboxByFacebookPageID_NilDB_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInboxByFacebookPageID("page123")
|
|
})
|
|
}
|
|
|
|
func TestFB_validInstagramVerifyToken_Empty_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
assert.False(t, h.validInstagramVerifyToken(""))
|
|
}
|
|
|
|
func TestFB_validInstagramVerifyToken_EnvToken_Cov3(t *testing.T) {
|
|
t.Setenv("IG_VERIFY_TOKEN", "mytoken")
|
|
h := &FacebookWebhookHandler{}
|
|
assert.True(t, h.validInstagramVerifyToken("mytoken"))
|
|
}
|
|
|
|
func TestFB_validInstagramVerifyToken_EnvToken2_Cov3(t *testing.T) {
|
|
t.Setenv("IG_VERIFY_TOKEN", "")
|
|
t.Setenv("INSTAGRAM_VERIFY_TOKEN", "ig_token_2")
|
|
h := &FacebookWebhookHandler{}
|
|
assert.True(t, h.validInstagramVerifyToken("ig_token_2"))
|
|
}
|
|
|
|
func TestFB_verifyInstagramSignature_EmptyHeader_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/", nil, nil)
|
|
err := h.verifyInstagramSignature(c, []byte("body"), nil)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestFB_instagramAppSecrets_Empty_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
secrets := h.instagramAppSecrets(nil)
|
|
// Without env vars set, should return empty or near-empty slice
|
|
assert.NotNil(t, secrets)
|
|
}
|
|
|
|
func TestFB_parseChannelConfig_Empty_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
config := h.parseChannelConfig(stubInbox_Cov3("", ""))
|
|
assert.NotNil(t, config)
|
|
}
|
|
|
|
func TestFB_parseChannelConfig_BadJSON_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
config := h.parseChannelConfig(stubInbox_Cov3("not json", ""))
|
|
assert.NotNil(t, config)
|
|
}
|
|
|
|
func TestFB_resolveVerifyToken_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
token := h.resolveVerifyToken(stubInbox_Cov3(`{"webhook_verify_token":"tok123"}`, ""))
|
|
assert.Equal(t, "tok123", token)
|
|
}
|
|
|
|
func TestFB_resolveVerifyToken_NoToken_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
token := h.resolveVerifyToken(stubInbox_Cov3(`{}`, ""))
|
|
assert.Equal(t, "", token)
|
|
}
|
|
|
|
func TestFB_resolveAppSecret_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
secret := h.resolveAppSecret(stubInbox_Cov3(`{"app_secret":"secret123"}`, ""))
|
|
assert.Equal(t, "secret123", secret)
|
|
}
|
|
|
|
func TestFB_resolveAppSecret_NoSecret_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
secret := h.resolveAppSecret(stubInbox_Cov3(`{}`, ""))
|
|
assert.Equal(t, "", secret)
|
|
}
|
|
|
|
func TestFB_persistFacebookReceipt_NilPersister_Cov3(t *testing.T) {
|
|
h := &FacebookWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
h.persistFacebookReceipt(nil, nil, nil)
|
|
})
|
|
}
|
|
|
|
func TestFB_millisToTime_Zero_Cov3(t *testing.T) {
|
|
result := millisToTime(0)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestFB_millisToTime_Negative_Cov3(t *testing.T) {
|
|
result := millisToTime(-1)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestFB_millisToTime_Valid_Cov3(t *testing.T) {
|
|
result := millisToTime(1609459200000)
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, int64(1609459200), result.Unix())
|
|
}
|
|
|
|
func TestFB_parseOptionalUintParam_Empty_Cov3(t *testing.T) {
|
|
val, err := parseOptionalUintParam("")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, uint(0), val)
|
|
}
|
|
|
|
func TestFB_parseOptionalUintParam_Valid_Cov3(t *testing.T) {
|
|
val, err := parseOptionalUintParam("42")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, uint(42), val)
|
|
}
|
|
|
|
func TestFB_parseOptionalUintParam_Invalid_Cov3(t *testing.T) {
|
|
_, err := parseOptionalUintParam("abc")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// ============================================================
|
|
// Telegram Webhook
|
|
// ============================================================
|
|
|
|
func TestTelegram_HandleWebhook_MissingBotToken_Cov3(t *testing.T) {
|
|
h := &TelegramWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/telegram/", []byte(`{}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTelegramWebhook(c)
|
|
})
|
|
// Even with nil db, should return OK because bot_token is empty path
|
|
_ = w
|
|
}
|
|
|
|
func TestTelegram_HandleWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := &TelegramWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/telegram/123456:ABC", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTelegramWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestTelegram_HandleWebhook_BadJSON_Cov3(t *testing.T) {
|
|
h := &TelegramWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/telegram/123456:ABC", []byte("not json"), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTelegramWebhook(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestTelegram_HandleWebhook_NilDB_Cov3(t *testing.T) {
|
|
h := &TelegramWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/telegram/123456:ABC", []byte(`{"update_id":1}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTelegramWebhook(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestTelegram_lookupInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &TelegramWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInbox("some_token")
|
|
})
|
|
}
|
|
|
|
func TestTelegram_maskBotToken_Long_Cov3(t *testing.T) {
|
|
result := maskBotToken("1234567890:ABC-DEF")
|
|
assert.True(t, strings.HasPrefix(result, "12345678"))
|
|
assert.True(t, strings.HasSuffix(result, "..."))
|
|
}
|
|
|
|
func TestTelegram_maskBotToken_Short_Cov3(t *testing.T) {
|
|
result := maskBotToken("short")
|
|
assert.Equal(t, "short", result)
|
|
}
|
|
|
|
// ============================================================
|
|
// Twilio Webhook
|
|
// ============================================================
|
|
|
|
func TestTwilio_HandleInboundSMS_MissingPhone_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/sms/", nil, nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioInboundSMS(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestTwilio_HandleInboundSMS_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/sms/+1234567890", []byte("Body=hi"), nil)
|
|
c.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioInboundSMS(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestTwilio_HandleCallback_NilHandler_Cov3(t *testing.T) {
|
|
var h *TwilioWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/twilio/", []byte("Body=hi"), nil)
|
|
h.HandleTwilioCallback(c)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_HandleCallback_BadForm_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/twilio/", []byte("Body=hi"), nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioCallback(c)
|
|
})
|
|
// ParseForm may succeed or fail depending on broken reader; just don't panic
|
|
}
|
|
|
|
func TestTwilio_HandleCallback_NilTwilioWebhook_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/twilio/", []byte("Body=hi"), nil)
|
|
c.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioCallback(c)
|
|
})
|
|
_ = w
|
|
}
|
|
|
|
func TestTwilio_HandleDeliveryStatus_BadForm_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/twilio/status/+1234567890", []byte(""), nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioDeliveryStatus(c)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_HandleDeliveryStatus_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/twilio/status/+1234567890", []byte("MessageSid=SM123&MessageStatus=delivered"), nil)
|
|
c.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioDeliveryStatus(c)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_HandleDeliveryStatus_NoPhone_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/twilio/status/", []byte("MessageSid=SM123&MessageStatus=delivered"), nil)
|
|
c.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTwilioDeliveryStatus(c)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_lookupInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInbox(1)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_lookupInboxByPhoneNumber_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInboxByPhoneNumber("+1234567890")
|
|
})
|
|
}
|
|
|
|
func TestTwilio_normalizeTwilioPhone_Empty_Cov3(t *testing.T) {
|
|
assert.Equal(t, "", normalizeTwilioPhone(""))
|
|
}
|
|
|
|
func TestTwilio_normalizeTwilioPhone_PlusPrefix_Cov3(t *testing.T) {
|
|
assert.Equal(t, "+1234567890", normalizeTwilioPhone("+1234567890"))
|
|
}
|
|
|
|
func TestTwilio_normalizeTwilioPhone_NoPlus_Cov3(t *testing.T) {
|
|
assert.Equal(t, "+1234567890", normalizeTwilioPhone("1234567890"))
|
|
}
|
|
|
|
func TestTwilio_mapTwilioMessageStatus_Sent_Cov3(t *testing.T) {
|
|
status, ok := mapTwilioMessageStatus("sent")
|
|
assert.True(t, ok)
|
|
_ = status
|
|
}
|
|
|
|
func TestTwilio_mapTwilioMessageStatus_Delivered_Cov3(t *testing.T) {
|
|
status, ok := mapTwilioMessageStatus("delivered")
|
|
assert.True(t, ok)
|
|
_ = status
|
|
}
|
|
|
|
func TestTwilio_mapTwilioMessageStatus_Read_Cov3(t *testing.T) {
|
|
status, ok := mapTwilioMessageStatus("read")
|
|
assert.True(t, ok)
|
|
_ = status
|
|
}
|
|
|
|
func TestTwilio_mapTwilioMessageStatus_Failed_Cov3(t *testing.T) {
|
|
status, ok := mapTwilioMessageStatus("failed")
|
|
assert.True(t, ok)
|
|
_ = status
|
|
}
|
|
|
|
func TestTwilio_mapTwilioMessageStatus_Unknown_Cov3(t *testing.T) {
|
|
_, ok := mapTwilioMessageStatus("unknown")
|
|
assert.False(t, ok)
|
|
}
|
|
|
|
func TestTwilio_twilioExternalError_NoError_Cov3(t *testing.T) {
|
|
result := twilioExternalError("", "msg", "delivered")
|
|
assert.Equal(t, "", result)
|
|
}
|
|
|
|
func TestTwilio_twilioExternalError_WithMessage_Cov3(t *testing.T) {
|
|
result := twilioExternalError("12345", "some error", "failed")
|
|
assert.Equal(t, "12345 - some error", result)
|
|
}
|
|
|
|
func TestTwilio_twilioExternalError_NoMessage_Cov3(t *testing.T) {
|
|
result := twilioExternalError("12345", "", "failed")
|
|
assert.Equal(t, "Twilio delivery failed with error code 12345", result)
|
|
}
|
|
|
|
func TestTwilio_twilioExternalError_Undelivered_Cov3(t *testing.T) {
|
|
result := twilioExternalError("99999", "undelivered msg", "undelivered")
|
|
assert.Equal(t, "99999 - undelivered msg", result)
|
|
}
|
|
|
|
func TestTwilio_lookupDeliveryStatusInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupDeliveryStatusInbox(nil)
|
|
})
|
|
}
|
|
|
|
func TestTwilio_lookupCallbackInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &TwilioWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupCallbackInbox(nil)
|
|
})
|
|
}
|
|
|
|
// ============================================================
|
|
// TikTok Webhook
|
|
// ============================================================
|
|
|
|
func TestTikTok_HandleWebhook_NilHandler_Cov3(t *testing.T) {
|
|
var h *TikTokWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/tiktok/biz123", []byte(`{}`), nil)
|
|
h.HandleTikTokWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestTikTok_HandleWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/tiktok/biz123", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTikTokWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestTikTok_HandleWebhook_SigFail_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/tiktok/biz123", []byte(`{"biz_id":"biz123"}`), map[string]string{
|
|
"Tiktok-Signature": "1234.abcd",
|
|
})
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTikTokWebhook(c)
|
|
})
|
|
// Should return Unauthorized due to signature verification failure
|
|
_ = w
|
|
}
|
|
|
|
func TestTikTok_HandleWebhook_MissingBusinessID_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/tiktok", []byte(`{}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTikTokWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestTikTok_HandleVerification_BadBody_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/tiktok/verify", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleTikTokVerification(c)
|
|
})
|
|
}
|
|
|
|
func TestTikTok_HandleVerification_BadJSON_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/tiktok/verify", []byte("not json"), nil)
|
|
h.HandleTikTokVerification(c)
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
}
|
|
|
|
func TestTikTok_HandleVerification_Success_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/tiktok/verify", []byte(`{"challenge":"mychallenge"}`), nil)
|
|
h.HandleTikTokVerification(c)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
var resp map[string]interface{}
|
|
json.Unmarshal(w.Body.Bytes(), &resp)
|
|
assert.Equal(t, "mychallenge", resp["challenge"])
|
|
}
|
|
|
|
func TestTikTok_lookupInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInbox(1)
|
|
})
|
|
}
|
|
|
|
func TestTikTok_lookupInboxByBusinessID_NilDB_Cov3(t *testing.T) {
|
|
h := &TikTokWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInboxByBusinessID("biz123")
|
|
})
|
|
}
|
|
|
|
func TestTikTok_extractTikTokBusinessID_BizID_Cov3(t *testing.T) {
|
|
result := extractTikTokBusinessID([]byte(`{"biz_id":"biz123"}`))
|
|
assert.Equal(t, "biz123", result)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokBusinessID_BusinessID_Cov3(t *testing.T) {
|
|
result := extractTikTokBusinessID([]byte(`{"business_id":"b456"}`))
|
|
assert.Equal(t, "b456", result)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokBusinessID_DataNested_Cov3(t *testing.T) {
|
|
result := extractTikTokBusinessID([]byte(`{"data":{"tiktok_business_id":"tb789"}}`))
|
|
assert.Equal(t, "tb789", result)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokBusinessID_BadJSON_Cov3(t *testing.T) {
|
|
result := extractTikTokBusinessID([]byte("not json"))
|
|
assert.Equal(t, "", result)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokBusinessID_Empty_Cov3(t *testing.T) {
|
|
result := extractTikTokBusinessID([]byte(`{}`))
|
|
assert.Equal(t, "", result)
|
|
}
|
|
|
|
func TestTikTok_verifyTikTokSignature_Empty_Cov3(t *testing.T) {
|
|
err := verifyTikTokSignature("", []byte("body"), time.Now())
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokSignatureParts_Empty_Cov3(t *testing.T) {
|
|
ts, sig := extractTikTokSignatureParts("")
|
|
assert.Equal(t, int64(0), ts)
|
|
assert.Equal(t, "", sig)
|
|
}
|
|
|
|
func TestTikTok_extractTikTokSignatureParts_Valid_Cov3(t *testing.T) {
|
|
ts, sig := extractTikTokSignatureParts("t=1234567890,s=abcdef")
|
|
assert.Equal(t, int64(1234567890), ts)
|
|
assert.Equal(t, "abcdef", sig)
|
|
}
|
|
|
|
func TestTikTok_tiktokDataString_Nil_Cov3(t *testing.T) {
|
|
result := tiktokDataString(nil, "message_id")
|
|
assert.Equal(t, "", result)
|
|
}
|
|
|
|
// ============================================================
|
|
// Email Webhook
|
|
// ============================================================
|
|
|
|
func TestEmail_HandleWebhook_InvalidInboxID_Cov3(t *testing.T) {
|
|
h := &EmailWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/email/abc", []byte(`{}`), nil)
|
|
h.HandleEmailWebhook(c)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestEmail_HandleWebhook_NilDB_Cov3(t *testing.T) {
|
|
h := &EmailWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/email/999", []byte(`{}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleEmailWebhook(c)
|
|
})
|
|
_ = w
|
|
}
|
|
|
|
func TestEmail_HandleVerification_Cov3(t *testing.T) {
|
|
h := &EmailWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/email/999", nil, nil)
|
|
h.HandleEmailVerification(c)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
// ============================================================
|
|
// LINE Webhook
|
|
// ============================================================
|
|
|
|
func TestLINE_HandleWebhook_MissingChannelID_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/line/", []byte(`{}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleLineWebhook(c)
|
|
})
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestLINE_HandleWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/line/chan123", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleLineWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestLINE_HandleWebhook_NilDB_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/line/chan123", []byte(`{"events":[]}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleLineWebhook(c)
|
|
})
|
|
_ = w
|
|
}
|
|
|
|
func TestLINE_HandleVerification_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/line/verify", nil, nil)
|
|
h.HandleLineVerification(c)
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestLINE_lookupInbox_NilDB_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInbox(1)
|
|
})
|
|
}
|
|
|
|
func TestLINE_lookupInboxByLineChannelID_NilDB_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
safeCall_Cov3(t, func() {
|
|
_, _ = h.lookupInboxByLineChannelID("chan123")
|
|
})
|
|
}
|
|
|
|
func TestLINE_parseChannelConfig_Empty_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
config := h.parseChannelConfig(stubInbox_Cov3("", ""))
|
|
assert.NotNil(t, config)
|
|
}
|
|
|
|
func TestLINE_parseChannelConfig_BadJSON_Cov3(t *testing.T) {
|
|
h := &LineWebhookHandler{}
|
|
config := h.parseChannelConfig(stubInbox_Cov3("not json", ""))
|
|
assert.NotNil(t, config)
|
|
}
|
|
|
|
// ============================================================
|
|
// Shopify Webhook
|
|
// ============================================================
|
|
|
|
func TestShopify_HandleWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: "secret"}
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/shopify", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleShopifyWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestShopify_HandleWebhook_HMACFail_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: "secret"}
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/shopify", []byte(`{"shop_domain":"test.myshopify.com"}`), map[string]string{
|
|
"X-Shopify-Hmac-SHA256": "invalid",
|
|
})
|
|
c.Request.Header.Set("X-Shopify-Hmac-SHA256", "invalid")
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleShopifyWebhook(c)
|
|
})
|
|
// With a valid secret and bad signature, should return 401
|
|
_ = w
|
|
}
|
|
|
|
func TestShopify_HandleWebhook_NoSecret_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: ""}
|
|
t.Setenv("SHOPIFY_CLIENT_SECRET", "")
|
|
c, w := makeGinContext_Cov3("POST", "/webhooks/shopify", []byte(`{}`), nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleShopifyWebhook(c)
|
|
})
|
|
_ = w
|
|
}
|
|
|
|
func TestShopify_verifyHMAC_NoSecret_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{clientSecret: ""}
|
|
t.Setenv("SHOPIFY_CLIENT_SECRET", "")
|
|
err := h.verifyHMAC("sig", []byte("body"))
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestShopify_verifyHMAC_EmptySig_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{clientSecret: "secret"}
|
|
err := h.verifyHMAC("", []byte("body"))
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestShopify_verifyHMAC_BadSig_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{clientSecret: "secret"}
|
|
err := h.verifyHMAC("badsig", []byte("body"))
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestShopify_deleteShopifyHooksByDomain_NilDB_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: "secret"}
|
|
err := h.deleteShopifyHooksByDomain(nil, "test.myshopify.com")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestShopify_findShopifyHookByDomain_NilDB_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: "secret"}
|
|
_, err := h.findShopifyHookByDomain(nil, "test.myshopify.com")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestShopify_shopifyHooks_NilDB_Cov3(t *testing.T) {
|
|
h := &ShopifyWebhookHandler{db: nil, clientSecret: "secret"}
|
|
_, err := h.shopifyHooks(nil, "test.myshopify.com")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// ============================================================
|
|
// Webhook Handler (webhook_handler.go) — Handle
|
|
// ============================================================
|
|
|
|
func TestWebhookHandler_Handle_NilHandler_Cov3(t *testing.T) {
|
|
var h *WebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/test", []byte(`{}`), nil)
|
|
h.Handle(c)
|
|
})
|
|
}
|
|
|
|
// ============================================================
|
|
// WhatsApp Webhook — constructor + delegates
|
|
// ============================================================
|
|
|
|
func TestWhatsApp_NewHandler_Cov3(t *testing.T) {
|
|
h := NewWhatsAppWebhookHandler(nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestWhatsApp_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewWhatsAppWebhookHandler(nil, nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestWhatsApp_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewWhatsAppWebhookHandler(nil, nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestWhatsApp_HandleVerification_Cov3(t *testing.T) {
|
|
h := NewWhatsAppWebhookHandler(nil, nil, nil)
|
|
c, w := makeGinContext_Cov3("GET", "/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=tok&hub.challenge=chal", nil, nil)
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleWhatsAppVerification(c)
|
|
})
|
|
_ = w
|
|
}
|
|
|
|
func TestWhatsApp_HandleWebhook_NilHandler_Cov3(t *testing.T) {
|
|
var h *WhatsAppWebhookHandler
|
|
safeCall_Cov3(t, func() {
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/whatsapp", []byte(`{}`), nil)
|
|
h.HandleWhatsAppWebhook(c)
|
|
})
|
|
}
|
|
|
|
func TestWhatsApp_HandleWebhook_BadBody_Cov3(t *testing.T) {
|
|
h := NewWhatsAppWebhookHandler(nil, nil, nil)
|
|
c, _ := makeGinContext_Cov3("POST", "/webhooks/whatsapp", nil, nil)
|
|
c.Request.Body = brokenBodyReader_Cov3{}
|
|
safeCall_Cov3(t, func() {
|
|
h.HandleWhatsAppWebhook(c)
|
|
})
|
|
}
|
|
|
|
// ============================================================
|
|
// IncomingPersister — SetWorkerPool, SetSearchIndexer, NewIncomingPersister
|
|
// ============================================================
|
|
|
|
func TestIncomingPersister_SetWorkerPool_Nil_Cov3(t *testing.T) {
|
|
p := NewIncomingPersister(nil)
|
|
p.SetWorkerPool(nil)
|
|
}
|
|
|
|
func TestIncomingPersister_SetSearchIndexer_Nil_Cov3(t *testing.T) {
|
|
p := NewIncomingPersister(nil)
|
|
p.SetSearchIndexer(nil)
|
|
}
|
|
|
|
func TestIncomingPersister_NewWithDispatcher_Cov3(t *testing.T) {
|
|
safeCall_Cov3(t, func() {
|
|
p := NewIncomingPersister(nil, nil)
|
|
_ = p
|
|
})
|
|
}
|
|
|
|
// ============================================================
|
|
// IncomingPersister Jobs helpers
|
|
// ============================================================
|
|
|
|
func TestJobs_validProviderMessageStatus_Cov3(t *testing.T) {
|
|
assert.True(t, validProviderMessageStatus("sent"))
|
|
assert.False(t, validProviderMessageStatus("invalid"))
|
|
}
|
|
|
|
func TestJobs_validProviderMessageStatusTransition_Cov3(t *testing.T) {
|
|
assert.True(t, validProviderMessageStatusTransition("sent", "delivered"))
|
|
assert.False(t, validProviderMessageStatusTransition("delivered", "sent"))
|
|
}
|
|
|
|
func TestJobs_providerMessageStatusRank_Cov3(t *testing.T) {
|
|
r1 := providerMessageStatusRank("sent")
|
|
r2 := providerMessageStatusRank("delivered")
|
|
assert.True(t, r2 > r1)
|
|
}
|
|
|
|
func TestJobs_setProviderMessageExternalError_Cov3(t *testing.T) {
|
|
result := setProviderMessageExternalError(datatypes.JSON(nil), "", "err1")
|
|
_ = result
|
|
}
|
|
|
|
func TestJobs_timeToUnixNano_Cov3(t *testing.T) {
|
|
tm := time.Now()
|
|
result := timeToUnixNano(&tm)
|
|
assert.Equal(t, tm.UnixNano(), result)
|
|
}
|
|
|
|
func TestJobs_timeToUnixNano_Nil_Cov3(t *testing.T) {
|
|
result := timeToUnixNano(nil)
|
|
assert.Equal(t, int64(0), result)
|
|
}
|
|
|
|
func TestJobs_unixNanoToTime_Cov3(t *testing.T) {
|
|
result := unixNanoToTime(0)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestJobs_unixNanoToTime_Valid_Cov3(t *testing.T) {
|
|
now := time.Now()
|
|
result := unixNanoToTime(now.UnixNano())
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestJobs_incomingMessageQueue_Cov3(t *testing.T) {
|
|
q := incomingMessageQueue(channel.ChannelType("test"))
|
|
_ = q
|
|
}
|
|
|
|
// ============================================================
|
|
// IncomingPersister — validateIncomingMessage
|
|
// ============================================================
|
|
|
|
func TestPersister_validateIncomingMessage_NilMsg_Cov3(t *testing.T) {
|
|
p := NewIncomingPersister(nil)
|
|
safeCall_Cov3(t, func() {
|
|
_ = validateIncomingMessage(p, nil, nil)
|
|
})
|
|
}
|
|
|
|
// ============================================================
|
|
// Facebook constructor + WithWorkerPool + WithSearchIndexer
|
|
// ============================================================
|
|
|
|
func TestFB_NewHandler_Cov3(t *testing.T) {
|
|
h := NewFacebookWebhookHandler(nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestFB_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewFacebookWebhookHandler(nil, nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestFB_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewFacebookWebhookHandler(nil, nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
// ============================================================
|
|
// Telegram constructor + WithWorkerPool + WithSearchIndexer
|
|
// ============================================================
|
|
|
|
func TestTelegram_NewHandler_Cov3(t *testing.T) {
|
|
h := NewTelegramWebhookHandler(nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestTelegram_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewTelegramWebhookHandler(nil, nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestTelegram_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewTelegramWebhookHandler(nil, nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
// ============================================================
|
|
// TikTok constructor + WithWorkerPool + WithSearchIndexer
|
|
// ============================================================
|
|
|
|
func TestTikTok_NewHandler_Cov3(t *testing.T) {
|
|
h := NewTikTokWebhookHandler(nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestTikTok_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewTikTokWebhookHandler(nil, nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestTikTok_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewTikTokWebhookHandler(nil, nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
// ============================================================
|
|
// Twilio constructor + WithWorkerPool + WithSearchIndexer
|
|
// ============================================================
|
|
|
|
func TestTwilio_NewHandler_Cov3(t *testing.T) {
|
|
h := NewTwilioWebhookHandler(nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestTwilio_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewTwilioWebhookHandler(nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestTwilio_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewTwilioWebhookHandler(nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
// ============================================================
|
|
// LINE constructor + WithWorkerPool + WithSearchIndexer
|
|
// ============================================================
|
|
|
|
func TestLINE_NewHandler_Cov3(t *testing.T) {
|
|
h := NewLineWebhookHandler(nil, nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
func TestLINE_WithWorkerPool_Cov3(t *testing.T) {
|
|
h := NewLineWebhookHandler(nil, nil, nil, nil)
|
|
result := h.WithWorkerPool(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
func TestLINE_WithSearchIndexer_Cov3(t *testing.T) {
|
|
h := NewLineWebhookHandler(nil, nil, nil, nil)
|
|
result := h.WithSearchIndexer(nil)
|
|
assert.NotNil(t, result)
|
|
}
|
|
|
|
// ============================================================
|
|
// Email constructor
|
|
// ============================================================
|
|
|
|
func TestEmail_NewHandler_Cov3(t *testing.T) {
|
|
h := NewEmailWebhookHandler(nil, nil, nil)
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
// ============================================================
|
|
// Shopify constructor
|
|
// ============================================================
|
|
|
|
func TestShopify_NewHandler_Cov3(t *testing.T) {
|
|
h := NewShopifyWebhookHandler(nil, "secret")
|
|
assert.NotNil(t, h)
|
|
}
|
|
|
|
// ============================================================
|
|
// Helpers and stubs
|
|
// ============================================================
|
|
|
|
// brokenBodyReader_Cov3 is an io.ReadCloser that always returns an error on Read.
|
|
type brokenBodyReader_Cov3 struct{}
|
|
|
|
func (brokenBodyReader_Cov3) Read(p []byte) (int, error) { return 0, assertError_Cov3 }
|
|
func (brokenBodyReader_Cov3) Close() error { return nil }
|
|
|
|
// stubInbox_Cov3 creates an Inbox with the given channel config JSON.
|
|
func stubInbox_Cov3(configJSON string, _ string) *model.Inbox {
|
|
return &model.Inbox{
|
|
ChannelConfig: configJSON,
|
|
}
|
|
}
|
|
|
|
// assertError_Cov3 is a sentinel error for broken body reader.
|
|
var assertError_Cov3 = &testError_Cov3{}
|
|
|
|
type testError_Cov3 struct{}
|
|
|
|
func (testError_Cov3) Error() string { return "read error" }
|
|
|
|
// Ensure imports are used
|
|
var _ = channel.ChannelType("test")
|
|
var _ = datatypes.JSON(nil)
|