Files
gochat/backend/internal/channel/whatsapp/coverage6_test.go
T
Rogeeandrogee 2b182f9956 H-300: wire Captain Skills into Web runtime (#48)
* H-300: wire Captain Skills into Web runtime

* H-300: enforce effective model and conservative skill budget

* H-300: fix CI gosec step

* ci: extend golangci-lint timeout

* fix lint findings across backend

* fix(push): resolve delivery protocol blockers

* test(repository): close SQLite test databases

* test(repository): reuse SQLite schema per package

* H-307: restore backend Go cache in CI

* H-307: prefetch modules before cold lint

* H-307: resolve govulncheck security gate

* H-307: build lint with patched Go toolchain

* H-307: clear remaining security scan findings

---------

Co-authored-by: Rogee <rogee@ipao.vip>
2026-08-19 07:08:14 +08:00

673 lines
24 KiB
Go

package whatsapp
import (
"context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/gochat/gochat/internal/channel"
"github.com/gochat/gochat/internal/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// ===========================
// WhatsAppProvider tests
// ===========================
func TestWhatsAppProvider_Type_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
assert.Equal(t, channel.ChannelWhatsApp, p.Type())
}
func TestWhatsAppProvider_Name_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
assert.Equal(t, "WhatsApp", p.Name())
}
func TestWhatsAppProvider_Description_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
assert.NotEmpty(t, p.Description())
}
func TestWhatsAppProvider_ConfigSchema_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
schema := p.ConfigSchema()
require.NotNil(t, schema)
assert.Equal(t, "object", schema.Type)
assert.Contains(t, schema.Required, "provider")
assert.Contains(t, schema.Required, "phone_number_id")
assert.Contains(t, schema.Required, "access_token")
}
func TestWhatsAppProvider_DefaultConfig_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
cfg := p.DefaultConfig()
assert.Equal(t, "whatsapp_cloud", cfg["provider"])
assert.Contains(t, cfg, "phone_number_id")
assert.Contains(t, cfg, "access_token")
}
func TestWhatsAppProvider_Capabilities_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
caps := p.Capabilities()
assert.True(t, caps.SupportsAttachments)
assert.True(t, caps.SupportsDeliveryStatus)
assert.True(t, caps.SupportsReplies)
assert.True(t, caps.SupportsTemplates)
assert.Equal(t, 4096, caps.MaxTextLength)
}
func TestWhatsAppProvider_ValidateConfig_NoProvider_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{})
require.Error(t, err)
assert.Contains(t, err.Error(), "provider is required")
}
func TestWhatsAppProvider_ValidateConfig_InvalidProvider_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "invalid",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "invalid provider")
}
func TestWhatsAppProvider_ValidateConfig_NoPhone_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "whatsapp_cloud",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "phone_number_id")
}
func TestWhatsAppProvider_ValidateConfig_NoToken_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "whatsapp_cloud",
"phone_number_id": "123",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "access_token")
}
func TestWhatsAppProvider_ValidateConfig_CloudNoVerifyToken_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "whatsapp_cloud",
"phone_number_id": "123",
"access_token": "token",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "webhook_verify_token")
}
func TestWhatsAppProvider_ValidateConfig_360NoAPIKey_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "360dialog",
"phone_number_id": "123",
"access_token": "token",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "api_key")
}
func TestWhatsAppProvider_ValidateConfig_CloudSuccess_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "whatsapp_cloud",
"phone_number_id": "123",
"access_token": "token",
"webhook_verify_token": "verify",
})
require.NoError(t, err)
}
func TestWhatsAppProvider_ValidateConfig_360Success_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.ValidateConfig(context.Background(), channel.ChannelConfig{
"provider": "360dialog",
"phone_number_id": "123",
"access_token": "token",
"api_key": "d360_key",
})
require.NoError(t, err)
}
func TestWhatsAppProvider_OAuthConfig_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
oauth := p.OAuthConfig()
require.NotNil(t, oauth)
assert.Equal(t, "whatsapp", oauth.Provider)
assert.True(t, oauth.RequiresRefresh)
}
func TestWhatsAppProvider_BuildAuthURL_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
url, err := p.BuildAuthURL(context.Background(), 42, "https://example.com/callback")
require.NoError(t, err)
assert.Contains(t, url, "redirect_uri=https://example.com/callback")
assert.Contains(t, url, "state=42")
}
func TestWhatsAppProvider_ExchangeToken_Cov6(t *testing.T) {
t.Skip("hits real Facebook API - no way to mock the hardcoded URL")
}
func TestWhatsAppProvider_RefreshToken_Cloud_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
// Test 360dialog path (permanent key, no API call)
result, err := p.RefreshToken(context.Background(), &model.Inbox{}, channel.ChannelConfig{
"provider": "360dialog",
"access_token": "permanent_key",
})
require.NoError(t, err)
require.NotNil(t, result)
assert.Equal(t, "permanent_key", result.AccessToken)
}
func TestWhatsAppProvider_RefreshToken_UnknownProvider_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
_, err := p.RefreshToken(context.Background(), &model.Inbox{}, channel.ChannelConfig{
"provider": "unknown",
})
require.Error(t, err)
}
func TestWhatsAppProvider_CheckAuthorizationError_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
assert.False(t, p.CheckAuthorizationError(context.Background(), nil))
assert.False(t, p.CheckAuthorizationError(context.Background(), waTestErr6("some error")))
assert.True(t, p.CheckAuthorizationError(context.Background(), waTestErr6("code 190")))
assert.True(t, p.CheckAuthorizationError(context.Background(), waTestErr6("access_token invalid")))
assert.True(t, p.CheckAuthorizationError(context.Background(), waTestErr6("authorization failed")))
assert.True(t, p.CheckAuthorizationError(context.Background(), waTestErr6("permission denied")))
}
func TestWhatsAppProvider_OnReauthorization_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.OnReauthorization(context.Background(), &model.Inbox{})
require.NoError(t, err)
}
func TestWhatsAppProvider_OnCreate_Cloud_Cov6(t *testing.T) {
t.Skip("hits real WhatsApp API - registerCloudWebhook uses hardcoded URL")
}
func TestWhatsAppProvider_OnCreate_360Dialog_Cov6(t *testing.T) {
t.Skip("hits real 360dialog API - register360DialogWebhook uses hardcoded URL")
}
func TestWhatsAppProvider_OnCreate_UnknownProvider_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ID = 1
cfg, err := p.OnCreate(context.Background(), inbox, channel.ChannelConfig{
"provider": "unknown",
})
require.NoError(t, err)
assert.NotNil(t, cfg)
}
func TestWhatsAppProvider_OnDestroy_Cloud_Cov6(t *testing.T) {
t.Skip("hits real WhatsApp API - unregisterCloudWebhook uses hardcoded URL")
}
func TestWhatsAppProvider_OnDestroy_360Dialog_Cov6(t *testing.T) {
t.Skip("hits real 360dialog API - unregister360DialogWebhook uses hardcoded URL")
}
func TestWhatsAppProvider_OnDestroy_Unknown_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
err := p.OnDestroy(context.Background(), inbox, channel.ChannelConfig{
"provider": "unknown",
})
require.NoError(t, err)
}
func TestWhatsAppProvider_ProcessIncoming_BadJSON_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
_, err := p.ProcessIncoming(context.Background(), inbox, []byte("bad json"))
require.Error(t, err)
}
func TestWhatsAppProvider_ProcessIncoming_NoPipeline_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
_, err := p.ProcessIncoming(context.Background(), inbox, []byte(`{}`))
// Will panic or error because pipeline is nil
_ = err
}
func TestWhatsAppProvider_ValidateWebhookRequest_Cloud_NoSig_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"whatsapp_cloud","access_token":"token"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "X-Hub-Signature-256")
}
func TestWhatsAppProvider_ValidateWebhookRequest_Cloud_NoToken_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"whatsapp_cloud"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"X-Hub-Signature-256": "sha256=abc"},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "access_token")
}
func TestWhatsAppProvider_ValidateWebhookRequest_Cloud_BadSig_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"whatsapp_cloud","access_token":"mysecret"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"X-Hub-Signature-256": "sha256=bad"},
Body: []byte(`{"test":"data"}`),
})
require.Error(t, err)
assert.Contains(t, err.Error(), "signature")
}
func TestWhatsAppProvider_ValidateWebhookRequest_Cloud_ValidSig_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
body := []byte(`{"test":"data"}`)
secret := "mysecret"
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
sig := "sha256=" + hex.EncodeToString(mac.Sum(nil))
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"whatsapp_cloud","access_token":"mysecret"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"X-Hub-Signature-256": sig},
Body: body,
})
require.NoError(t, err)
}
func TestWhatsAppProvider_ValidateWebhookRequest_360_NoHeader_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"360dialog","api_key":"d360_key"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "D360-API-KEY")
}
func TestWhatsAppProvider_ValidateWebhookRequest_360_NoConfigKey_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"360dialog"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"D360-API-KEY": "some_key"},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "api_key")
}
func TestWhatsAppProvider_ValidateWebhookRequest_360_BadKey_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"360dialog","api_key":"correct_key"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"D360-API-KEY": "wrong_key"},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "invalid D360-API-KEY")
}
func TestWhatsAppProvider_ValidateWebhookRequest_360_ValidKey_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"360dialog","api_key":"correct_key"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{"D360-API-KEY": "correct_key"},
})
require.NoError(t, err)
}
func TestWhatsAppProvider_ValidateWebhookRequest_Unknown_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"unknown"}`
err := p.ValidateWebhookRequest(context.Background(), inbox, &channel.WebhookRequest{
Method: "POST",
Headers: map[string]string{},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "unknown")
}
func TestWhatsAppProvider_GetContactProfile_UnknownProvider_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `{"provider":"unknown"}`
_, err := p.GetContactProfile(context.Background(), inbox, "12345")
require.Error(t, err)
assert.Contains(t, err.Error(), "unknown provider")
}
func TestWhatsAppProvider_GetContactProfile_Cloud_Cov6(t *testing.T) {
t.Skip("hits real WhatsApp API - getCloudContactProfile uses hardcoded URL")
}
func TestWhatsAppProvider_GetContactProfile_360Dialog_Cov6(t *testing.T) {
t.Skip("hits real 360dialog API - get360DialogContactProfile uses hardcoded URL")
}
func TestWhatsAppProvider_GetContactProfile_BadConfig_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ChannelConfig = `bad json`
_, err := p.GetContactProfile(context.Background(), inbox, "12345")
require.Error(t, err)
}
func TestWhatsAppProvider_SendMessage_NoRepo_Cov6(t *testing.T) {
t.Skip("network test")
p := NewWhatsAppProvider(nil, nil, nil)
inbox := &model.Inbox{}
inbox.ID = 1
_, err := p.SendMessage(context.Background(), inbox, &model.Message{}, &model.Contact{})
// Will panic or error because repository is nil
_ = err
}
// ===========================
// verifyCloudSignature tests
// ===========================
func TestWhatsAppProvider_verifyCloudSignature_Valid_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
body := []byte(`{"test":"data"}`)
secret := "mysecret"
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
sig := "sha256=" + hex.EncodeToString(mac.Sum(nil))
err := p.verifyCloudSignature(body, sig, secret)
require.NoError(t, err)
}
func TestWhatsAppProvider_verifyCloudSignature_Invalid_Cov6(t *testing.T) {
p := NewWhatsAppProvider(nil, nil, nil)
err := p.verifyCloudSignature([]byte("data"), "sha256=bad", "secret")
require.Error(t, err)
}
// ===========================
// MediaService tests
// ===========================
func TestNewMediaService_Cov6(t *testing.T) {
ms := NewMediaService("https://graph.facebook.com/v18.0", "/tmp/test")
require.NotNil(t, ms)
assert.Equal(t, "https://graph.facebook.com/v18.0", ms.graphAPIBase)
assert.Equal(t, "/tmp/test", ms.storagePath)
}
func TestMediaService_RetrieveMediaURL_Success_Cov6(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.NoError(t, json.NewEncoder(w).Encode(MediaRetrieveResponse{
URL: "https://cdn.example.com/media.jpg",
MimeType: "image/jpeg",
}))
}))
defer ts.Close()
ms := NewMediaService(ts.URL, "/tmp/test")
resp, err := ms.RetrieveMediaURL(context.Background(), "media123", "token")
require.NoError(t, err)
require.NotNil(t, resp)
assert.Equal(t, "https://cdn.example.com/media.jpg", resp.URL)
}
func TestMediaService_RetrieveMediaURL_Error_Cov6(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer ts.Close()
ms := NewMediaService(ts.URL, "/tmp/test")
_, err := ms.RetrieveMediaURL(context.Background(), "media123", "token")
require.Error(t, err)
}
func TestMediaService_DownloadAttachment_Success_Cov6(t *testing.T) {
t.Skip("network test")
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("fake image data"))
require.NoError(t, err)
}))
defer ts.Close()
ms := NewMediaService(ts.URL, t.TempDir())
path, err := ms.DownloadAttachment(context.Background(), ts.URL, "testfile.jpg", "token")
require.NoError(t, err)
assert.NotEmpty(t, path)
}
func TestMediaService_DownloadAttachment_ErrorStatus_Cov6(t *testing.T) {
t.Skip("network test")
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
defer ts.Close()
ms := NewMediaService(ts.URL, t.TempDir())
_, err := ms.DownloadAttachment(context.Background(), ts.URL, "testfile.jpg", "token")
require.Error(t, err)
}
func TestMediaService_UploadMedia_FileNotFound_Cov6(t *testing.T) {
t.Skip("network test")
ms := NewMediaService("https://graph.facebook.com/v18.0", "/tmp/test")
_, err := ms.UploadMedia(context.Background(), "phone123", "token", "/nonexistent/file.jpg", "image/jpeg")
require.Error(t, err)
}
func TestMediaService_UploadMedia_Success_Cov6(t *testing.T) {
t.Skip("network test")
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.NoError(t, json.NewEncoder(w).Encode(MediaUploadResponse{ID: "uploaded_media_123"}))
}))
defer ts.Close()
// Create a temp file to upload
tmpDir := t.TempDir()
tmpFile := tmpDir + "/test.jpg"
err := writeFile6(tmpFile, []byte("fake image"))
require.NoError(t, err)
ms := NewMediaService(ts.URL, tmpDir)
id, err := ms.UploadMedia(context.Background(), "phone123", "token", tmpFile, "image/jpeg")
require.NoError(t, err)
assert.Equal(t, "uploaded_media_123", id)
}
func TestMediaService_UploadAttachment_NoLocalPath_Cov6(t *testing.T) {
ms := NewMediaService("https://graph.facebook.com/v18.0", "/tmp/test")
_, err := ms.UploadAttachment(context.Background(), "phone123", "token", &channel.Attachment{
Extra: map[string]interface{}{},
})
require.Error(t, err)
assert.Contains(t, err.Error(), "local_path")
}
func TestMediaService_UploadFromURL_Success_Cov6(t *testing.T) {
fileServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write([]byte("downloaded file content")); err != nil {
panic(err)
}
}))
defer fileServer.Close()
uploadServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.NoError(t, json.NewEncoder(w).Encode(MediaUploadResponse{ID: "uploaded_from_url_123"}))
}))
defer uploadServer.Close()
tmpDir := t.TempDir()
ms := NewMediaService(uploadServer.URL, tmpDir)
id, err := ms.UploadFromURL(context.Background(), "phone123", "token", fileServer.URL+"/file.jpg", "image/jpeg")
require.NoError(t, err)
assert.Equal(t, "uploaded_from_url_123", id)
}
func TestMediaService_UploadFromURL_BadSource_Cov6(t *testing.T) {
ms := NewMediaService("https://graph.facebook.com/v18.0", t.TempDir())
_, err := ms.UploadFromURL(context.Background(), "phone123", "token", "http://127.0.0.1:1/nonexistent", "image/jpeg")
require.Error(t, err)
}
func TestMediaService_UploadFromURL_SourceError_Cov6(t *testing.T) {
fileServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}))
defer fileServer.Close()
ms := NewMediaService("https://graph.facebook.com/v18.0", t.TempDir())
_, err := ms.UploadFromURL(context.Background(), "phone123", "token", fileServer.URL+"/file.jpg", "image/jpeg")
require.Error(t, err)
}
func TestMediaService_DownloadWhatsAppMedia_Success_Cov6(t *testing.T) {
t.Skip("hits real CDN URL - cannot mock DownloadWhatsAppMedia download step")
}
func TestMediaService_DownloadWhatsAppDocument_Cov6(t *testing.T) {
t.Skip("hits real WhatsApp API - DownloadWhatsAppDocument uses hardcoded URL")
}
// ===========================
// Helper function tests
// ===========================
func TestGenerateFilenameFromMediaID_Cov6(t *testing.T) {
name := generateFilenameFromMediaID("123", "image")
assert.Contains(t, name, "123")
assert.Contains(t, name, ".jpg")
}
func TestGenerateFilenameFromURL_Cov6(t *testing.T) {
name := generateFilenameFromURL("https://example.com/path/to/file.jpg")
assert.Equal(t, "file.jpg", name)
}
func TestGenerateFilenameFromURL_WithQuery_Cov6(t *testing.T) {
name := generateFilenameFromURL("https://example.com/path/to/file.jpg?token=abc")
assert.Equal(t, "file.jpg", name)
}
func TestGenerateFilenameFromURL_Empty_Cov6(t *testing.T) {
name := generateFilenameFromURL("")
assert.NotEmpty(t, name)
}
func TestMimeTypeFromWhatsAppType_Cov6(t *testing.T) {
assert.Equal(t, "image/jpeg", mimeTypeFromWhatsAppType("image"))
assert.Equal(t, "video/mp4", mimeTypeFromWhatsAppType("video"))
assert.Equal(t, "audio/ogg; codecs=opus", mimeTypeFromWhatsAppType("audio"))
assert.Equal(t, "application/pdf", mimeTypeFromWhatsAppType("document"))
assert.Equal(t, "image/webp", mimeTypeFromWhatsAppType("sticker"))
assert.Equal(t, "text/plain", mimeTypeFromWhatsAppType("location"))
assert.Equal(t, "text/plain", mimeTypeFromWhatsAppType("contacts"))
assert.Equal(t, "application/octet-stream", mimeTypeFromWhatsAppType("unknown"))
}
func TestExtensionFromWhatsAppType_Cov6(t *testing.T) {
assert.Equal(t, ".jpg", extensionFromWhatsAppType("image"))
assert.Equal(t, ".mp4", extensionFromWhatsAppType("video"))
assert.Equal(t, ".ogg", extensionFromWhatsAppType("audio"))
assert.Equal(t, ".pdf", extensionFromWhatsAppType("document"))
assert.Equal(t, ".webp", extensionFromWhatsAppType("sticker"))
assert.Equal(t, "", extensionFromWhatsAppType("unknown"))
}
func TestGetFileSize_Cov6(t *testing.T) {
// Nonexistent file
size := getFileSize("/nonexistent/path/file.jpg")
assert.Equal(t, int64(0), size)
}
func TestWhatsAppSupportedContentTypes_Cov6(t *testing.T) {
types := WhatsAppSupportedContentTypes()
assert.NotEmpty(t, types)
assert.Contains(t, types, "image/jpeg")
assert.Contains(t, types, "video/mp4")
assert.Contains(t, types, "application/pdf")
}
func TestIsWhatsAppSupportedContentType_Cov6(t *testing.T) {
assert.True(t, IsWhatsAppSupportedContentType("image/jpeg"))
assert.True(t, IsWhatsAppSupportedContentType("IMAGE/JPEG"))
assert.True(t, IsWhatsAppSupportedContentType("application/pdf"))
assert.True(t, IsWhatsAppSupportedContentType("application/custom"))
assert.False(t, IsWhatsAppSupportedContentType("text/xml"))
}
func TestWhatsAppMaxMediaSize_Cov6(t *testing.T) {
assert.Equal(t, int64(5*1024*1024), WhatsAppMaxMediaSize("image"))
assert.Equal(t, int64(16*1024*1024), WhatsAppMaxMediaSize("video"))
assert.Equal(t, int64(16*1024*1024), WhatsAppMaxMediaSize("audio"))
assert.Equal(t, int64(100*1024*1024), WhatsAppMaxMediaSize("document"))
assert.Equal(t, int64(500*1024), WhatsAppMaxMediaSize("sticker"))
assert.Equal(t, int64(16*1024*1024), WhatsAppMaxMediaSize("unknown"))
}
func TestWACloudAPIError_Error_Cov6(t *testing.T) {
e := WACloudAPIError{Code: 401, Message: "Unauthorized", Type: "OAuth", ErrorSubcode: 463}
str := e.Error()
assert.Contains(t, str, "401")
assert.Contains(t, str, "Unauthorized")
}
// ===========================
// Type tests
// ===========================
func TestWAWebhookEvent_Unmarshal_Cov6(t *testing.T) {
payload := `{"object":"whatsapp_business_account","entry":[{"id":"waba1","changes":[{"field":"messages","value":{"messaging_product":"whatsapp","messages":[{"from":"123456","id":"msg1","timestamp":"1234567890","type":"text","text":{"body":"hello"}}]}}]}]}`
var event WAWebhookEvent
err := json.Unmarshal([]byte(payload), &event)
require.NoError(t, err)
assert.Equal(t, "whatsapp_business_account", event.Object)
assert.Len(t, event.Entry, 1)
}
// waTestErr6 creates a simple error for WhatsApp tests
type waTestErr6 string
func (e waTestErr6) Error() string { return string(e) }
func writeFile6(path string, data []byte) error {
return os.WriteFile(path, data, 0644)
}