Files
Rogeeandrogee b31b1b9562 H-337: restore Web widget reply visibility (#64)
* H-337: restore widget reply delivery

* H-337: harden widget conversation ownership

---------

Co-authored-by: Rogee <rogee@ipao.vip>
2026-08-20 22:22:27 +08:00

231 lines
6.8 KiB
Go

package ws
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)
func init() {
gin.SetMode(gin.TestMode)
}
func TestNewWSAuthenticator_Cov4(t *testing.T) {
a := NewWSAuthenticator(nil, nil)
assert.NotNil(t, a)
}
func TestWSAuthenticator_Authenticate_NoToken_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
a := NewWSAuthenticator(nil, nil)
_, err := a.Authenticate(c)
assert.Error(t, err)
assert.Contains(t, err.Error(), "authentication required")
}
func TestWSAuthenticator_Authenticate_PubsubTokenNoUserID_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?pubsub_token=token123", nil)
a := NewWSAuthenticator(nil, nil)
_, err := a.Authenticate(c)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid pubsub_token")
}
func TestWSAuthenticator_Authenticate_PubsubTokenInvalidUserID_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?pubsub_token=token123&user_id=abc", nil)
a := NewWSAuthenticator(nil, nil)
_, err := a.Authenticate(c)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid user_id")
}
func TestWSAuthenticator_Authenticate_JWTFail_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?token=invalidjwt", nil)
a := NewWSAuthenticator(nil, nil)
// nil jwtService will panic — use safeCall
defer func() { _ = recover() }()
_, _ = a.Authenticate(c)
}
func TestWSAuthenticator_Authorize_NoAccountID_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
a := NewWSAuthenticator(nil, nil)
claims := &WSClaims{AccountID: 1}
err := a.Authorize(claims, c)
assert.NoError(t, err)
}
func TestWSAuthenticator_Authorize_InvalidAccountID_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?account_id=abc", nil)
a := NewWSAuthenticator(nil, nil)
claims := &WSClaims{AccountID: 1}
err := a.Authorize(claims, c)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid account_id")
}
func TestWSAuthenticator_Authorize_AccountMismatch_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?account_id=999", nil)
a := NewWSAuthenticator(nil, nil)
claims := &WSClaims{AccountID: 1}
err := a.Authorize(claims, c)
assert.Error(t, err)
assert.Contains(t, err.Error(), "does not have access")
}
func TestWSAuthenticator_Authorize_AccountMatch_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?account_id=1", nil)
a := NewWSAuthenticator(nil, nil)
claims := &WSClaims{AccountID: 1}
err := a.Authorize(claims, c)
assert.NoError(t, err)
}
func TestWSAuthenticator_AuthenticateAndServeWS_Unauthorized_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
a := NewWSAuthenticator(nil, nil)
a.AuthenticateAndServeWS(c)
assert.Equal(t, http.StatusUnauthorized, w.Code)
}
func TestWSAuthenticator_AuthenticateAndServeWS_AuthorizeFail_Cov4(t *testing.T) {
// Can't easily test success path without a JWT service, but we can test
// that with no auth, it returns 401
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?account_id=999", nil)
a := NewWSAuthenticator(nil, nil)
a.AuthenticateAndServeWS(c)
assert.Equal(t, http.StatusUnauthorized, w.Code)
}
func TestExtractWSToken_QueryParam_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?token=mytoken", nil)
token := extractWSToken(c)
assert.Equal(t, "mytoken", token)
}
func TestExtractWSToken_AccessTokenParam_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws?access-token=mytoken", nil)
token := extractWSToken(c)
assert.Equal(t, "mytoken", token)
}
func TestExtractWSToken_AuthHeader_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
c.Request.Header.Set("Authorization", "Bearer mytoken")
token := extractWSToken(c)
assert.Equal(t, "mytoken", token)
}
func TestExtractWSToken_AuthHeaderNoBearer_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
c.Request.Header.Set("Authorization", "Basic mytoken")
token := extractWSToken(c)
assert.Empty(t, token)
}
func TestExtractWSToken_Empty_Cov4(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/ws", nil)
token := extractWSToken(c)
assert.Empty(t, token)
}
func TestParseWSQueryParams_Cov4(t *testing.T) {
query := url.Values{}
query.Set("account_id", "1")
query.Set("conversation_id", "2")
query.Set("inbox_id", "3")
query.Set("pubsub_token", "token123")
query.Set("user_id", "4")
query.Set("token", "jwt_token")
params := ParseWSQueryParams(query)
assert.Equal(t, "1", params["account_id"])
assert.Equal(t, "2", params["conversation_id"])
assert.Equal(t, "3", params["inbox_id"])
assert.Equal(t, "token123", params["pubsub_token"])
assert.Equal(t, "4", params["user_id"])
assert.Equal(t, "jwt_token", params["token"])
}
func TestParseWSQueryParams_Empty_Cov4(t *testing.T) {
query := url.Values{}
params := ParseWSQueryParams(query)
assert.NotNil(t, params)
assert.Empty(t, params)
}
func TestParseWSQueryParams_Partial_Cov4(t *testing.T) {
query := url.Values{}
query.Set("account_id", "1")
params := ParseWSQueryParams(query)
assert.Equal(t, "1", params["account_id"])
_, exists := params["conversation_id"]
assert.False(t, exists)
}
func TestWSClaims_Struct_Cov4(t *testing.T) {
claims := &WSClaims{
UserID: 1,
AccountID: 2,
Role: "agent",
Provider: "jwt",
PubsubToken: "token",
IsContact: false,
ContactID: 0,
InboxID: 0,
}
assert.Equal(t, uint(1), claims.UserID)
assert.Equal(t, "agent", claims.Role)
assert.False(t, claims.IsContact)
}
func TestWSClaims_Contact_Cov4(t *testing.T) {
claims := &WSClaims{
UserID: 100,
AccountID: 2,
Role: "contact",
Provider: "pubsub_token",
PubsubToken: "token",
IsContact: true,
ContactID: 100,
InboxID: 5,
}
assert.True(t, claims.IsContact)
assert.Equal(t, "contact", claims.Role)
assert.Equal(t, uint(100), claims.ContactID)
}