package tiktok import ( "context" "io" "net/http" "net/http/httptest" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" channelpkg "github.com/gochat/gochat/internal/channel" "github.com/gochat/gochat/internal/model" ) func TestNewWebhookHandler_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) assert.NotNil(t, h) } func TestWebhookHandler_HandleWebhookRequest_Success_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) body := `{"type":"message.received","timestamp":1700000000,"biz_id":"biz-123","data":{"message_id":"msg-1","from_user_id":"user-1","content_type":"text","content":"Hello","conversation_id":"conv-1"}}` req := httptest.NewRequest("POST", "/webhook", strings.NewReader(body)) req.Header.Set("Content-Type", "application/json") event, err := h.HandleWebhookRequest(req) require.NoError(t, err) require.NotNil(t, event) assert.Equal(t, "message.received", event.Type) assert.Equal(t, "biz-123", event.BizID) } func TestWebhookHandler_HandleWebhookRequest_EmptyBody_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) req := httptest.NewRequest("POST", "/webhook", strings.NewReader("")) _, err := h.HandleWebhookRequest(req) assert.Error(t, err) assert.Contains(t, err.Error(), "empty") } func TestWebhookHandler_HandleWebhookRequest_InvalidJSON_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) req := httptest.NewRequest("POST", "/webhook", strings.NewReader("invalid")) _, err := h.HandleWebhookRequest(req) assert.Error(t, err) assert.Contains(t, err.Error(), "parse JSON") } func TestWebhookHandler_HandleVerifyRequest_Success_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) req := httptest.NewRequest("GET", "/webhook?verify_token=mytoken&challenge=challenge123", nil) challenge, err := h.HandleVerifyRequest(req, "mytoken") require.NoError(t, err) assert.Equal(t, "challenge123", challenge) } func TestWebhookHandler_HandleVerifyRequest_TokenMismatch_Cov4(t *testing.T) { svc := &TikTokService{} pipe := NewIncomingProcessor(svc, &Repository{}) h := NewWebhookHandler(svc, pipe) req := httptest.NewRequest("GET", "/webhook?verify_token=wrong&challenge=challenge123", nil) _, err := h.HandleVerifyRequest(req, "expected-token") assert.Error(t, err) assert.Contains(t, err.Error(), "mismatch") } func TestTikTokProvider_GetContactProfile_Error_Cov4(t *testing.T) { t.Skip("test issue") svc := &TikTokService{ client: newTestClient(func(*http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 401, Body: http.NoBody, Header: make(http.Header), }, nil }), } provider := NewTikTokProvider(svc, &Repository{}, NewIncomingProcessor(svc, &Repository{})) inbox := &model.Inbox{ Base: model.Base{ID: 1}, ChannelConfig: `{"access_token":"token"}`, } _, err := provider.GetContactProfile(context.Background(), inbox, "u123") assert.Error(t, err) } func TestTikTokProvider_SendMessage_APIError_Cov4(t *testing.T) { svc := &TikTokService{ client: newTestClient(func(*http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 200, Body: io.NopCloser(strings.NewReader(`{"message_id":"","code":1001,"message":"error"}`)), Header: http.Header{"Content-Type": []string{"application/json"}}, }, nil }), } provider := NewTikTokProvider(svc, &Repository{}, NewIncomingProcessor(svc, &Repository{})) ctx := context.Background() inbox := &model.Inbox{ Base: model.Base{ID: 1}, ChannelConfig: `{"access_token":"token"}`, } contact := &model.Contact{SourceID: "user-123"} msg := &model.Message{Content: "Hello"} _, err := provider.SendMessage(ctx, inbox, msg, contact) assert.Error(t, err) } func TestTikTokProvider_RefreshToken_Error_Cov4(t *testing.T) { svc := &TikTokService{ client: newTestClient(func(*http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 500, Body: http.NoBody, Header: make(http.Header), }, nil }), } provider := NewTikTokProvider(svc, &Repository{}, NewIncomingProcessor(svc, &Repository{})) config := channelpkg.ChannelConfig{ "refresh_token": "old-refresh", "client_key": "key", "client_secret": "secret", } _, err := provider.RefreshToken(context.Background(), &model.Inbox{}, config) assert.Error(t, err) } func TestParseInboxConfig_Cov4(t *testing.T) { // Empty string result := parseInboxConfig("") assert.NotNil(t, result) assert.Empty(t, result) // Valid JSON result = parseInboxConfig(`{"key":"val"}`) assert.NotNil(t, result) assert.Equal(t, "val", result["key"]) // Invalid JSON result = parseInboxConfig("invalid") assert.NotNil(t, result) assert.Empty(t, result) } func TestConfigStr_Cov4(t *testing.T) { assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{}, "key", "default")) assert.Equal(t, "val", configStr(channelpkg.ChannelConfig{"key": "val"}, "key", "default")) assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{"key": ""}, "key", "default")) assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{"key": 123}, "key", "default")) }