Files
gochat/internal/channel/whatsapp/webhook_handler_test.go
T

87 lines
2.6 KiB
Go

package whatsapp
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/gochat/gochat/internal/model"
channelmodel "github.com/gochat/gochat/internal/model/channel"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func newWhatsAppWebhookTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
if err := db.AutoMigrate(&model.Inbox{}, &channelmodel.ChannelWhatsApp{}); err != nil {
t.Fatalf("migrate whatsapp models: %v", err)
}
return db
}
func TestWhatsAppWebhookLookupByVerifyToken(t *testing.T) {
db := newWhatsAppWebhookTestDB(t)
inbox := model.Inbox{AccountID: 1, Name: "wa", ChannelType: "whatsapp", ChannelID: 1, Enabled: true}
if err := db.Create(&inbox).Error; err != nil {
t.Fatalf("create inbox: %v", err)
}
channel := channelmodel.ChannelWhatsApp{
AccountID: 1,
InboxID: inbox.ID,
PhoneNumber: "+15551234567",
PhoneNumberID: "phone-number-id",
AccessToken: "access-token",
Provider: "whatsapp_cloud",
WebhookVerifyToken: "verify-token",
ProviderConfig: `{"app_secret":"app-secret"}`,
BusinessAccountID: "waba-id",
WhatsAppAccountName: "WA",
}
if err := db.Create(&channel).Error; err != nil {
t.Fatalf("create whatsapp channel: %v", err)
}
repo := NewRepository(db)
provider := NewWhatsAppProvider(nil, repo, nil)
h := NewWebhookHandler(provider)
found, err := h.lookupByVerifyToken("verify-token")
if err != nil {
t.Fatalf("lookup verify token: %v", err)
}
if found.ID != channel.ID {
t.Fatalf("unexpected channel id: %d", found.ID)
}
if secret := resolveCloudAppSecret(found); secret != "app-secret" {
t.Fatalf("unexpected app secret: %q", secret)
}
}
func TestWhatsAppCloudSignatureUsesAppSecret(t *testing.T) {
gin.SetMode(gin.TestMode)
body := []byte(`{"object":"whatsapp_business_account"}`)
mac := hmac.New(sha256.New, []byte("app-secret"))
mac.Write(body)
signature := "sha256=" + hex.EncodeToString(mac.Sum(nil))
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodPost, "/webhooks/whatsapp/phone", nil)
c.Request.Header.Set("X-Hub-Signature-256", signature)
h := NewWebhookHandler(nil)
if err := h.verifyCloudSignature(c, body, "app-secret"); err != nil {
t.Fatalf("verify signature: %v", err)
}
if err := h.verifyCloudSignature(c, body, "wrong-secret"); err == nil {
t.Fatal("expected wrong app secret to fail")
}
}