* H-337: restore widget reply delivery * H-337: harden widget conversation ownership --------- Co-authored-by: Rogee <rogee@ipao.vip>
231 lines
6.8 KiB
Go
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)
|
|
}
|