Build and publish Docker images / Build and publish images (push) Successful in 2m10s
102 lines
3.8 KiB
Go
102 lines
3.8 KiB
Go
package widget
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gochat/gochat/internal/geoip"
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/datatypes"
|
|
)
|
|
|
|
type handlerGeoResolver struct {
|
|
location geoip.Location
|
|
seenIP net.IP
|
|
}
|
|
|
|
func (r *handlerGeoResolver) Lookup(ip net.IP) (geoip.Location, bool) {
|
|
r.seenIP = append(net.IP(nil), ip...)
|
|
return r.location, true
|
|
}
|
|
|
|
func TestWidgetHandler_ConfigUsesServerClientIPForAnonymousName(t *testing.T) {
|
|
db, router, handler := setupWidgetHandlerTest(t)
|
|
_, _ = seedWidgetHandlerData(t, db)
|
|
resolver := &handlerGeoResolver{location: geoip.Location{Province: "河北省", City: "保定市"}}
|
|
handler.widgetService.SetVisitorGeoResolver(resolver)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
req, err := http.NewRequest(http.MethodPost, "/api/v1/widget/config?website_token=handler_ws_token_123", nil)
|
|
require.NoError(t, err)
|
|
req.RemoteAddr = "203.0.113.20:4567"
|
|
router.ServeHTTP(recorder, req)
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
assert.Equal(t, "203.0.113.20", resolver.seenIP.String())
|
|
var payload map[string]any
|
|
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &payload))
|
|
contact, ok := payload["contact"].(map[string]any)
|
|
require.True(t, ok)
|
|
assert.Equal(t, "河北保定客户", contact["name"])
|
|
}
|
|
|
|
func TestWidgetHandler_InitIgnoresClientSuppliedIP(t *testing.T) {
|
|
db, router, handler := setupWidgetHandlerTest(t)
|
|
_, _ = seedWidgetHandlerData(t, db)
|
|
require.NoError(t, router.SetTrustedProxies(nil))
|
|
resolver := &handlerGeoResolver{location: geoip.Location{Province: "北京市", City: "北京市"}}
|
|
handler.widgetService.SetVisitorGeoResolver(resolver)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
req, err := http.NewRequest(http.MethodPost, "/widget/init", strings.NewReader(`{"website_token":"handler_ws_token_123","client_ip":"198.51.100.99"}`))
|
|
require.NoError(t, err)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-Forwarded-For", "198.51.100.99")
|
|
req.RemoteAddr = "203.0.113.21:4567"
|
|
router.ServeHTTP(recorder, req)
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
assert.Equal(t, "203.0.113.21", resolver.seenIP.String())
|
|
var contact model.Contact
|
|
require.NoError(t, db.First(&contact).Error)
|
|
assert.Equal(t, "北京客户", contact.Name)
|
|
}
|
|
|
|
func TestWidgetHandler_ConfigHonorsConfiguredTrustedProxyIP(t *testing.T) {
|
|
db, router, handler := setupWidgetHandlerTest(t)
|
|
_, _ = seedWidgetHandlerData(t, db)
|
|
require.NoError(t, router.SetTrustedProxies([]string{"203.0.113.0/24"}))
|
|
resolver := &handlerGeoResolver{location: geoip.Location{Province: "北京市", City: "北京市"}}
|
|
handler.widgetService.SetVisitorGeoResolver(resolver)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
req, err := http.NewRequest(http.MethodPost, "/api/v1/widget/config?website_token=handler_ws_token_123", nil)
|
|
require.NoError(t, err)
|
|
req.Header.Set("X-Forwarded-For", "198.51.100.44")
|
|
req.RemoteAddr = "203.0.113.21:4567"
|
|
router.ServeHTTP(recorder, req)
|
|
|
|
require.Equal(t, http.StatusOK, recorder.Code)
|
|
assert.Equal(t, "198.51.100.44", resolver.seenIP.String())
|
|
}
|
|
|
|
func TestWidgetContactFullPayloadDoesNotExposeVisitorMetadata(t *testing.T) {
|
|
contact := &model.Contact{
|
|
Name: "河北保定客户",
|
|
AdditionalAttributes: datatypes.JSON(`{"visitor_name_source":"ip_geolocation","visitor_province":"河北","visitor_city":"保定","customer_note":"keep"}`),
|
|
}
|
|
payload := widgetContactFullPayload(contact)
|
|
attributes, ok := payload["additional_attributes"].(map[string]any)
|
|
require.True(t, ok)
|
|
assert.Equal(t, "keep", attributes["customer_note"])
|
|
assert.NotContains(t, attributes, "visitor_name_source")
|
|
assert.NotContains(t, attributes, "visitor_province")
|
|
assert.NotContains(t, attributes, "visitor_city")
|
|
}
|